From 734fe91b90a1fc6b057132b8a2c46c87105ffc4c Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 18:23:31 +0200 Subject: [PATCH 001/109] Solved deadlock in python windows. --- .../include/py_loader/py_loader_impl.h | 2 ++ .../loaders/py_loader/source/py_loader_impl.c | 25 +++++++++++++++---- .../loaders/py_loader/source/py_loader_port.c | 22 ++++++++++++++++ .../py_loader/source/py_loader_threading.cpp | 2 +- source/ports/py_port/metacall/api.py | 9 ++++++- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/source/loaders/py_loader/include/py_loader/py_loader_impl.h b/source/loaders/py_loader/include/py_loader/py_loader_impl.h index f06b3d603..bc1a081ed 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader_impl.h +++ b/source/loaders/py_loader/include/py_loader/py_loader_impl.h @@ -62,6 +62,8 @@ PY_LOADER_NO_EXPORT int py_loader_impl_finalizer_object(loader_impl impl, PyObje PY_LOADER_NO_EXPORT PyObject *py_loader_impl_capsule_new_null(void); +PY_LOADER_NO_EXPORT int py_loader_impl_initialize_asyncio_module(loader_impl_py py_impl, const int host); + #ifdef __cplusplus } #endif diff --git a/source/loaders/py_loader/source/py_loader_impl.c b/source/loaders/py_loader/source/py_loader_impl.c index 477b7a4b0..1f9fc5e3d 100644 --- a/source/loaders/py_loader/source/py_loader_impl.c +++ b/source/loaders/py_loader/source/py_loader_impl.c @@ -2610,7 +2610,12 @@ int py_loader_impl_initialize_argv(loader_impl_py py_impl, int argc, char **argv static void PyCFunction_dealloc(PyObject *obj) { - py_loader_thread_acquire(); + const int gil_status = PyGILState_Check(); + + if (gil_status == 0) + { + py_loader_thread_acquire(); + } /* Check if we are passing our own hook to the callback */ if (PyCFunction_Check(obj) && PyCFunction_GET_FUNCTION(obj) == py_loader_impl_function_type_invoke) @@ -2624,6 +2629,7 @@ static void PyCFunction_dealloc(PyObject *obj) loader_impl_py_function_type_invoke_state invoke_state = PyCapsule_GetPointer(invoke_state_capsule, NULL); + /* Release the GIL and let the destroy be executed outside of Python (if it belongs to another language) */ py_loader_thread_release(); value_type_destroy(invoke_state->callback); py_loader_thread_acquire(); @@ -2636,7 +2642,10 @@ static void PyCFunction_dealloc(PyObject *obj) /* Call to the original meth_dealloc function */ py_loader_impl_pycfunction_dealloc(obj); - py_loader_thread_release(); + if (gil_status == 0) + { + py_loader_thread_release(); + } } loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration config) @@ -2760,10 +2769,16 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi goto error_after_import; } - /* Initialize asyncio module for supporting async */ - if (py_loader_impl_initialize_asyncio_module(py_impl, host) != 0) +#if defined(WIN32) || defined(_WIN32) + /* On Windows, the initialization of this module deadlocks, we delay it to the port on this case */ + if (host == 0) +#endif { - goto error_after_thread_background_module; + /* Initialize asyncio module for supporting async */ + if (py_loader_impl_initialize_asyncio_module(py_impl, host) != 0) + { + goto error_after_thread_background_module; + } } /* Initialize custom dict type */ diff --git a/source/loaders/py_loader/source/py_loader_port.c b/source/loaders/py_loader/source/py_loader_port.c index a5bf798ff..8f60578e3 100644 --- a/source/loaders/py_loader/source/py_loader_port.c +++ b/source/loaders/py_loader/source/py_loader_port.c @@ -890,6 +890,26 @@ static PyObject *py_loader_port_atexit(PyObject *self, PyObject *args) return Py_ReturnNone(); } +static PyObject *py_loader_port_asyncio_initialize(PyObject *self, PyObject *args) +{ + loader_impl impl = loader_get_impl(py_loader_tag); + const int host = loader_impl_get_option_host(impl); + loader_impl_py py_impl = loader_impl_get(impl); + + (void)self; + (void)args; + + if (impl != NULL) + { + if (py_loader_impl_initialize_asyncio_module(py_impl, host) != 0) + { + PyErr_SetString(PyExc_RuntimeErrorPtr(), "Failed to initialize asyncio module of Python Loader on MetaCall."); + } + } + + return Py_ReturnNone(); +} + static PyMethodDef metacall_methods[] = { { "metacall_load_from_file", py_loader_port_load_from_file, METH_VARARGS, "Loads a script from file." }, @@ -913,6 +933,8 @@ static PyMethodDef metacall_methods[] = { "Get the data which a value of type Pointer is pointing to." }, { "py_loader_port_atexit", py_loader_port_atexit, METH_NOARGS, "At exit function that will be executed when Python is host, for internal cleanup purposes." }, + { "py_loader_port_asyncio_initialize", py_loader_port_asyncio_initialize, METH_NOARGS, + "Initialization function that will be executed when Python is host, for internal initialization purposes." }, { NULL, NULL, 0, NULL } }; diff --git a/source/loaders/py_loader/source/py_loader_threading.cpp b/source/loaders/py_loader/source/py_loader_threading.cpp index 1b4041fbe..64a0ab7fb 100644 --- a/source/loaders/py_loader/source/py_loader_threading.cpp +++ b/source/loaders/py_loader/source/py_loader_threading.cpp @@ -69,7 +69,7 @@ int py_loader_thread_initialize(const int host) if (host == 1) { - int gil_status = PyGILState_Check(); + const int gil_status = PyGILState_Check(); PyGILState_STATE gstate = PyGILState_Ensure(); main_thread_state = PyThreadState_Get(); diff --git a/source/ports/py_port/metacall/api.py b/source/ports/py_port/metacall/api.py index 80586c86e..83f28da45 100644 --- a/source/ports/py_port/metacall/api.py +++ b/source/ports/py_port/metacall/api.py @@ -95,7 +95,14 @@ def metacall_module_load(): # Python Port must have been loaded at this point if 'py_port_impl_module' in sys.modules: - return sys.modules['py_port_impl_module'] + port = sys.modules['py_port_impl_module'] + + # For some reason, Windows deadlocks on initializing asyncio + # but if it is delayed, it works, so we initialize it after here + if sys.platform == 'win32': + port.py_loader_port_asyncio_initialize() + + return port else: raise ImportError( 'MetaCall was found but failed to load' From c1e74c827dd940d5b2c605bcf71883ea80217f27 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 22:37:58 +0200 Subject: [PATCH 002/109] Trying to solve configuration issues. --- source/configuration/source/configuration.c | 15 +++++++++++++++ .../configuration/source/configuration_object.c | 2 ++ 2 files changed, 17 insertions(+) diff --git a/source/configuration/source/configuration.c b/source/configuration/source/configuration.c index 8994e4bb0..f1f6e41f8 100644 --- a/source/configuration/source/configuration.c +++ b/source/configuration/source/configuration.c @@ -101,6 +101,21 @@ int configuration_initialize(const char *reader, const char *path, void *allocat } } +#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) + /* Windows MSVC stores the build folder in Debug/Release folders, so we must also check in the parent folder */ + if (global == NULL) + { + static const char configuration_default_path_win32[] = ".." ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR CONFIGURATION_DEFAULT_PATH; + + if (configuration_path_from_library_path(library_relative_path, configuration_default_path_win32, sizeof(configuration_default_path_win32)) == 0) + { + global = configuration_object_initialize(CONFIGURATION_GLOBAL_SCOPE, library_relative_path, NULL); + + path = library_relative_path; + } + } +#endif + if (global == NULL) { static const char relative_path[] = ".." ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR "share" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR "metacall" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR CONFIGURATION_DEFAULT_PATH; diff --git a/source/configuration/source/configuration_object.c b/source/configuration/source/configuration_object.c index f38298023..57c7ab9cd 100644 --- a/source/configuration/source/configuration_object.c +++ b/source/configuration/source/configuration_object.c @@ -96,6 +96,8 @@ configuration configuration_object_initialize(const char *name, const char *path if (path != NULL) { + log_write("metacall", LOG_LEVEL_DEBUG, "Trying to load configuration from %s", path); + config->source = configuration_object_read(path); if (config->source == NULL) From 4eda28a1f87c2778826a4ea28c36301211e771b2 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 23:07:30 +0200 Subject: [PATCH 003/109] Add more debug info to configuration. --- source/configuration/source/configuration.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/configuration/source/configuration.c b/source/configuration/source/configuration.c index f1f6e41f8..e72793a19 100644 --- a/source/configuration/source/configuration.c +++ b/source/configuration/source/configuration.c @@ -45,6 +45,8 @@ static int configuration_path_from_library_path(dynlink_path library_relative_pa return 1; } + log_write("metacall", LOG_LEVEL_DEBUG, "Finding configuration relative path %s to %s", relative_path, library_path); + /* Get the current folder without the library */ size = portability_path_get_directory_inplace(library_path, length + 1); @@ -102,7 +104,7 @@ int configuration_initialize(const char *reader, const char *path, void *allocat } #if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) - /* Windows MSVC stores the build folder in Debug/Release folders, so we must also check in the parent folder */ + /* Windows MSVC when running the tests, it has the binaries in Debug / Release folders, so we must also check in the parent folder */ if (global == NULL) { static const char configuration_default_path_win32[] = ".." ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR CONFIGURATION_DEFAULT_PATH; From e5f58ed87f622935a9fe2910d2adb55ff5d04e88 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 23:26:20 +0200 Subject: [PATCH 004/109] Add more debug info. --- source/portability/source/portability_library_path.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index 221d7a1cc..314e1fec2 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -196,6 +196,10 @@ int portability_library_path_find(const char name[], portability_library_path_st { const char *image_name = _dyld_get_image_name(image_index); + // TODO: Delete this + printf("Debug: %s\n", image_name); + fflush(stdout); + if (portability_library_path_ends_with(image_name, path) == 0) { size_t image_length = strnlen(image_name, PORTABILITY_PATH_SIZE); From 353e5b0cc447055fe53ecb01d5c8d339acae07b3 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 23:41:28 +0200 Subject: [PATCH 005/109] Debug macos. --- source/portability/source/portability_library_path.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index 314e1fec2..eb873d6c2 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -122,6 +122,8 @@ static int portability_library_path_list_phdr_callback(struct dl_phdr_info *info #endif +#include + int portability_library_path_find(const char name[], portability_library_path_str path, size_t *length) { #if defined(unix) || defined(__unix__) || defined(__unix) || \ From 611fb049ea45cc09d832ec443a9c39c265b1f13c Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 17 Jun 2025 23:54:48 +0200 Subject: [PATCH 006/109] Test with index 0. --- source/portability/source/portability_library_path.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index eb873d6c2..a1dba149b 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -194,7 +194,7 @@ int portability_library_path_find(const char name[], portability_library_path_st } /* Start from 1 so we avoid the executable itself */ - for (image_index = 1; image_index < size; ++image_index) + for (image_index = 0; image_index < size; ++image_index) { const char *image_name = _dyld_get_image_name(image_index); From 8160473677bf3f7972e34bac7cc267dd2cf8c3af Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 00:12:05 +0200 Subject: [PATCH 007/109] Add more debug info in macos. --- source/portability/source/portability_library_path.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index a1dba149b..5f457cbc0 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -199,7 +199,7 @@ int portability_library_path_find(const char name[], portability_library_path_st const char *image_name = _dyld_get_image_name(image_index); // TODO: Delete this - printf("Debug: %s\n", image_name); + printf("Debug: #%d / %d => %s\n", image_index, size, image_name); fflush(stdout); if (portability_library_path_ends_with(image_name, path) == 0) From c7a8ad3f0313ecb9b32707ac65471d36935469af Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 00:33:38 +0200 Subject: [PATCH 008/109] Add more debug info macos. --- source/portability/source/portability_library_path.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index 5f457cbc0..c94275d39 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -194,7 +194,7 @@ int portability_library_path_find(const char name[], portability_library_path_st } /* Start from 1 so we avoid the executable itself */ - for (image_index = 0; image_index < size; ++image_index) + for (image_index = 1; image_index < size; ++image_index) { const char *image_name = _dyld_get_image_name(image_index); @@ -202,7 +202,11 @@ int portability_library_path_find(const char name[], portability_library_path_st printf("Debug: #%d / %d => %s\n", image_index, size, image_name); fflush(stdout); - if (portability_library_path_ends_with(image_name, path) == 0) + printf("Debug ends with: %s | %s\n", image_name, path); + printf("Debug ends with: %s | %s\n", image_name, name); + fflush(stdout); + + if (portability_library_path_ends_with(image_name, name) == 0) { size_t image_length = strnlen(image_name, PORTABILITY_PATH_SIZE); @@ -218,6 +222,9 @@ int portability_library_path_find(const char name[], portability_library_path_st *length = image_length; } + printf("Debug ended with: %s | %s => %s\n", image_name, path, name); + fflush(stdout); + return 0; } } From 0e37d08553578bc879a026067263178a430475f3 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 00:45:52 +0200 Subject: [PATCH 009/109] Solve issue with macos. --- source/portability/source/portability_library_path.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index c94275d39..0558c515d 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -189,8 +189,9 @@ int portability_library_path_find(const char name[], portability_library_path_st if (portability_library_path_ends_with(name, "so") == 0 && name_dylib_length < PORTABILITY_PATH_SIZE) { - memcpy(path, name, sizeof(char) * (name_length - 2)); - memcpy(path, dylib_suffix, sizeof(dylib_suffix)); + const size_t base_length = sizeof(char) * (name_length - 2); + memcpy(path, name, base_length); + memcpy(&path[base_length], dylib_suffix, sizeof(dylib_suffix)); } /* Start from 1 so we avoid the executable itself */ @@ -206,7 +207,7 @@ int portability_library_path_find(const char name[], portability_library_path_st printf("Debug ends with: %s | %s\n", image_name, name); fflush(stdout); - if (portability_library_path_ends_with(image_name, name) == 0) + if (portability_library_path_ends_with(image_name, path) == 0) { size_t image_length = strnlen(image_name, PORTABILITY_PATH_SIZE); @@ -222,7 +223,7 @@ int portability_library_path_find(const char name[], portability_library_path_st *length = image_length; } - printf("Debug ended with: %s | %s => %s\n", image_name, path, name); + printf("------------------------------- Debug ended with: %s | %s => %s\n", image_name, path, name); fflush(stdout); return 0; From a6851fa1526b720f4b3f3f6d785c2a2ad63d5568 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 00:59:03 +0200 Subject: [PATCH 010/109] Solved issues on macos. --- .../portability/source/portability_library_path.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index 0558c515d..cda5f9cb3 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -122,8 +122,6 @@ static int portability_library_path_list_phdr_callback(struct dl_phdr_info *info #endif -#include - int portability_library_path_find(const char name[], portability_library_path_str path, size_t *length) { #if defined(unix) || defined(__unix__) || defined(__unix) || \ @@ -199,14 +197,6 @@ int portability_library_path_find(const char name[], portability_library_path_st { const char *image_name = _dyld_get_image_name(image_index); - // TODO: Delete this - printf("Debug: #%d / %d => %s\n", image_index, size, image_name); - fflush(stdout); - - printf("Debug ends with: %s | %s\n", image_name, path); - printf("Debug ends with: %s | %s\n", image_name, name); - fflush(stdout); - if (portability_library_path_ends_with(image_name, path) == 0) { size_t image_length = strnlen(image_name, PORTABILITY_PATH_SIZE); @@ -223,9 +213,6 @@ int portability_library_path_find(const char name[], portability_library_path_st *length = image_length; } - printf("------------------------------- Debug ended with: %s | %s => %s\n", image_name, path, name); - fflush(stdout); - return 0; } } From 46b74adeab2ecb915306f16536e0ce9a18b1a3dd Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 01:01:50 +0200 Subject: [PATCH 011/109] Update version to v0.9.9. Long live to Argentum Online. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b5d0ec558..6f060dcbc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.8 \ No newline at end of file +0.9.9 \ No newline at end of file From a090ae5b810ce40394bd574bdd8e704cbb347a88 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 19:42:10 +0200 Subject: [PATCH 012/109] Improve debugging tools for threading in python loader. --- .../loaders/py_loader/source/py_loader_impl.c | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/source/loaders/py_loader/source/py_loader_impl.c b/source/loaders/py_loader/source/py_loader_impl.c index 1f9fc5e3d..a5fa1d9ff 100644 --- a/source/loaders/py_loader/source/py_loader_impl.c +++ b/source/loaders/py_loader/source/py_loader_impl.c @@ -2396,6 +2396,13 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) "import asyncio\n" "import threading\n" "import sys\n" +#if DEBUG_ENABLED + "def trace_calls(frame, event, arg):\n" + " t = threading.current_thread()\n" + " print(f\"[{t.native_id}] {t.name}: {event} {frame.f_code.co_name}\")\n" + "threading.settrace(trace_calls)\n" + "sys.settrace(trace_calls)\n" +#endif "class ThreadLoop:\n" " def __init__(self, loop, t):\n" " self.loop = loop\n" @@ -2410,13 +2417,26 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) " tl.loop.call_soon_threadsafe(f.set_exception, exception)\n" "def background_loop(loop):\n" " asyncio.set_event_loop(loop)\n" - " loop.run_forever()\n" - " loop.run_until_complete(loop.shutdown_asyncgens())\n" - " loop.stop()\n" - " loop.close()\n" + " try:\n" + " loop.run_forever()\n" + " finally:\n" +#if DEBUG_ENABLED + " print('Loop stopping, cleaning up...', flush=True)\n" +#endif + " try:\n" + " loop.run_until_complete(loop.shutdown_asyncgens())\n" + " except Exception as e:\n" + " print(f\"Error during shutdown_asyncgens: {e}\", flush=True)\n" + " loop.close()\n" +#if DEBUG_ENABLED + " print('Event loop closed', flush=True)\n" +#endif "def start_background_loop():\n" " loop = asyncio.new_event_loop()\n" - " t = threading.Thread(target=background_loop, name='MetaCall asyncio event loop', args=(loop,), daemon=False)\n" +#if DEBUG_ENABLED + " loop.set_debug(True)\n" +#endif + " t = threading.Thread(target=background_loop, name='MetaCallEventLoop', args=(loop,), daemon=False)\n" " t.start()\n" " return ThreadLoop(loop, t)\n" "def send_background_loop(tl, coro, callback, capsule):\n" @@ -2427,9 +2447,18 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) /* Stop background loop enqueues at the end of the event loop the task to be finished, so effectively it waits until the event loop finishes */ "def stop_background_loop(tl, join):\n" +#if DEBUG_ENABLED + " print('Requesting loop to stop', flush=True)\n" +#endif " tl.loop.call_soon_threadsafe(tl.loop.stop)\n" " if join:\n" +#if DEBUG_ENABLED + " print('Waiting for thread to join', flush=True)\n" +#endif " tl.t.join()\n" +#if DEBUG_ENABLED + " print('Background loop stopped', flush=True)\n" +#endif "def atexit_background_loop(tl):\n" /* Checks if py_port_impl_module contains py_loader_port_atexit and executes it */ " getattr(sys.modules.get('py_port_impl_module'), 'py_loader_port_atexit', lambda: None)()\n" From e214b903397891e04d909be61f16f9c0e6c46c67 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 18 Jun 2025 19:42:44 +0200 Subject: [PATCH 013/109] Exit properly on CLI error. --- source/cli/metacallcli/source/application.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/cli/metacallcli/source/application.cpp b/source/cli/metacallcli/source/application.cpp index a8389d003..098f63900 100644 --- a/source/cli/metacallcli/source/application.cpp +++ b/source/cli/metacallcli/source/application.cpp @@ -49,7 +49,7 @@ void application::repl() } /* Register exit function */ - auto exit = [](size_t argc, void *args[], void *data) -> void * { + auto exit_command = [](size_t argc, void *args[], void *data) -> void * { (void)args; (void)data; @@ -67,11 +67,12 @@ void application::repl() return NULL; }; - int result = metacall_register_loaderv(metacall_loader("ext"), plugin_repl_handle, "exit", exit, METACALL_INVALID, 0, NULL); + int result = metacall_register_loaderv(metacall_loader("ext"), plugin_repl_handle, "exit", exit_command, METACALL_INVALID, 0, NULL); if (result != 0) { std::cout << "Exit function was not registered properly, return code: " << result << std::endl; + exit(1); } else { @@ -268,7 +269,7 @@ application::application(int argc, char *argv[]) : if (metacall_initialize() != 0) { /* Exit from application */ - return; + exit(1); } /* Initialize MetaCall arguments */ @@ -372,7 +373,7 @@ void application::arguments_parse(std::vector &arguments) { /* Stop loading more scripts */ std::cout << "Error: Failed to load script '" << script << "' with loader '" << safe_tag << "'" << std::endl; - return; + exit(1); } } } From 578dcfdc250962665581bb31b88c8283cb052b03 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Fri, 20 Jun 2025 00:37:47 +0200 Subject: [PATCH 014/109] Improve issues with ruby port. --- .../loaders/rb_loader/source/rb_loader_impl.c | 265 ++++++++++-------- .../loaders/rb_loader/source/rb_loader_port.c | 25 +- source/ports/rb_port/package/lib/metacall.rb | 24 ++ 3 files changed, 195 insertions(+), 119 deletions(-) diff --git a/source/loaders/rb_loader/source/rb_loader_impl.c b/source/loaders/rb_loader/source/rb_loader_impl.c index d35208391..325844066 100644 --- a/source/loaders/rb_loader/source/rb_loader_impl.c +++ b/source/loaders/rb_loader/source/rb_loader_impl.c @@ -89,6 +89,13 @@ typedef struct loader_impl_rb_funcall_protect_type ID id; } * loader_impl_rb_funcall_protect; +typedef struct loader_impl_rb_discover_module_protect_type +{ + loader_impl impl; + loader_impl_rb_module rb_module; + context ctx; +} * loader_impl_rb_discover_module_protect; + static class_interface rb_class_interface_singleton(void); static object_interface rb_object_interface_singleton(void); static void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_str, enum class_visibility_id visibility, const char *method_type_str, VALUE methods, int (*register_method)(klass, method)); @@ -1255,7 +1262,9 @@ loader_handle rb_loader_impl_load_from_file(loader_impl impl, const loader_path { #define rb_str_new_static_size(str) rb_str_new_static(str, sizeof(str) - 1) - VALUE wrapped_code = rb_str_plus(rb_str_new_static_size("module "), module_name); + VALUE wrapped_code = rb_str_new_static_size("require 'rubygems'\n"); + wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("module ")); + wrapped_code = rb_str_plus(wrapped_code, module_name); wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("\n")); wrapped_code = rb_str_plus(wrapped_code, module_data); wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("\nend")); @@ -1509,58 +1518,61 @@ void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_ VALUE name = rb_sym2str(rb_method); const char *method_name_str = RSTRING_PTR(name); - VALUE instance_method = rb_funcall(cls, rb_intern(method_type_str), 1, rb_method); - VALUE parameters = rb_funcallv(instance_method, rb_intern("parameters"), 0, NULL); - size_t args_it, args_count = RARRAY_LEN(parameters); - - log_write("metacall", LOG_LEVEL_DEBUG, "Method '%s' inside '%s' of type %s with %" PRIuS " parameters", method_name_str, class_name_str, method_type_str, args_count); - - /* - * TODO: - * Another alternative (for supporting types), which is not used in the current implementation, - * but it can simplify the parser, it's the following: - * - * - For classes: origin_file, definition_line = MyClass.instance_method(:foo).source_location - * - For plain functions: origin_file, definition_line = method(:foo).source_location - * - * Then: - * method_signature = IO.readlines(origin_file)[definition_line.pred] - * - * Now we have only the method signature, this is going to be less problematic than parsing - * the whole file as we are doing now (although for multi-line signatures it's going to be - * a little bit more complicated...) - * - * We can switch to completely duck typed approach (refactoring the tests) or we can use this - * simplified parsing approach and maintain types - */ - - method m = method_create(c, - method_name_str, - args_count, - (method_impl)instance_method, - visibility, - SYNCHRONOUS, /* There is not async functions in Ruby */ - NULL); - - signature s = method_signature(m); - - for (args_it = 0; args_it < args_count; ++args_it) + if (rb_respond_to(cls, RB_SYM2ID(rb_method))) { - VALUE parameter_pair = rb_ary_entry(parameters, args_it); - - if (RARRAY_LEN(parameter_pair) == 2) + VALUE instance_method = rb_funcall(cls, rb_intern(method_type_str), 1, rb_method); + VALUE parameters = rb_funcallv(instance_method, rb_intern("parameters"), 0, NULL); + size_t args_it, args_count = RARRAY_LEN(parameters); + + log_write("metacall", LOG_LEVEL_DEBUG, "Method '%s' inside '%s' of type %s with %" PRIuS " parameters", method_name_str, class_name_str, method_type_str, args_count); + + /* + * TODO: + * Another alternative (for supporting types), which is not used in the current implementation, + * but it can simplify the parser, it's the following: + * + * - For classes: origin_file, definition_line = MyClass.instance_method(:foo).source_location + * - For plain functions: origin_file, definition_line = method(:foo).source_location + * + * Then: + * method_signature = IO.readlines(origin_file)[definition_line.pred] + * + * Now we have only the method signature, this is going to be less problematic than parsing + * the whole file as we are doing now (although for multi-line signatures it's going to be + * a little bit more complicated...) + * + * We can switch to completely duck typed approach (refactoring the tests) or we can use this + * simplified parsing approach and maintain types + */ + + method m = method_create(c, + method_name_str, + args_count, + (method_impl)instance_method, + visibility, + SYNCHRONOUS, /* There is not async functions in Ruby */ + NULL); + + signature s = method_signature(m); + + for (args_it = 0; args_it < args_count; ++args_it) { - VALUE parameter_name_id = rb_ary_entry(parameter_pair, 1); - VALUE parameter_name = rb_sym2str(parameter_name_id); - const char *parameter_name_str = RSTRING_PTR(parameter_name); + VALUE parameter_pair = rb_ary_entry(parameters, args_it); - signature_set(s, args_it, parameter_name_str, NULL); + if (RARRAY_LEN(parameter_pair) == 2) + { + VALUE parameter_name_id = rb_ary_entry(parameter_pair, 1); + VALUE parameter_name = rb_sym2str(parameter_name_id); + const char *parameter_name_str = RSTRING_PTR(parameter_name); + + signature_set(s, args_it, parameter_name_str, NULL); + } } - } - if (register_method(c, m) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Ruby failed to register method '%s' in class '%s'", method_name_str, class_name_str); + if (register_method(c, m) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby failed to register method '%s' in class '%s'", method_name_str, class_name_str); + } } } } @@ -1587,15 +1599,12 @@ void rb_loader_impl_discover_attributes(klass c, const char *class_name_str, VAL } } -int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_module, context ctx) +static VALUE rb_loader_impl_discover_module_protect(VALUE args) { - log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader discovering:"); - - if (rb_module->empty == 0) - { - return 0; - } - + loader_impl_rb_discover_module_protect protect = (loader_impl_rb_discover_module_protect)args; + loader_impl impl = protect->impl; + loader_impl_rb_module rb_module = protect->rb_module; + context ctx = protect->ctx; VALUE instance_methods = rb_funcallv(rb_module->module, rb_intern("instance_methods"), 0, NULL); VALUE methods_size = rb_funcallv(instance_methods, rb_intern("size"), 0, NULL); int index, size = FIX2INT(methods_size); @@ -1630,7 +1639,7 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo if (scope_define(sp, function_name(f), v) != 0) { value_type_destroy(v); - return 1; + return INT2NUM(1); } else { @@ -1640,12 +1649,12 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo } else { - return 1; + return INT2NUM(1); } } else { - return 1; + return INT2NUM(1); } } } @@ -1659,80 +1668,106 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo { VALUE constant = rb_ary_entry(constants, index); - if (constant != Qnil) + if (constant != Qnil && RB_TYPE_P(constant, T_SYMBOL)) { - if (RB_TYPE_P(constant, T_SYMBOL)) - { - VALUE class_name = rb_sym2str(constant); - const char *class_name_str = RSTRING_PTR(class_name); - VALUE cls = rb_const_get_from(rb_module->module, rb_intern(class_name_str)); - loader_impl_rb_class rb_cls = malloc(sizeof(struct loader_impl_rb_class_type)); - klass c = class_create(class_name_str, ACCESSOR_TYPE_DYNAMIC, rb_cls, &rb_class_interface_singleton); + VALUE class_name = rb_sym2str(constant); + const char *class_name_str = RSTRING_PTR(class_name); + VALUE cls = rb_const_get_from(rb_module->module, rb_intern(class_name_str)); + loader_impl_rb_class rb_cls = malloc(sizeof(struct loader_impl_rb_class_type)); + klass c = class_create(class_name_str, ACCESSOR_TYPE_DYNAMIC, rb_cls, &rb_class_interface_singleton); - rb_cls->class = cls; - rb_cls->impl = impl; + rb_cls->class = cls; + rb_cls->impl = impl; - /* Discover methods */ - VALUE argv[1] = { Qtrue }; /* include_superclasses ? Qtrue : Qfalse; */ - VALUE methods = rb_class_public_instance_methods(1, argv, cls); /* argc, argv, cls */ - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "instance_method", methods, &class_register_method); + /* Discover methods */ + VALUE argv[1] = { Qtrue }; /* include_superclasses ? Qtrue : Qfalse; */ + VALUE methods = rb_class_public_instance_methods(1, argv, cls); /* argc, argv, cls */ + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "instance_method", methods, &class_register_method); - methods = rb_class_protected_instance_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "instance_method", methods, &class_register_method); + methods = rb_class_protected_instance_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "instance_method", methods, &class_register_method); - methods = rb_class_private_instance_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "instance_method", methods, &class_register_method); + methods = rb_class_private_instance_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "instance_method", methods, &class_register_method); #if RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 0 - methods = rb_obj_public_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "singleton_method", methods, &class_register_static_method); + methods = rb_obj_public_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "singleton_method", methods, &class_register_static_method); - methods = rb_obj_protected_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "singleton_method", methods, &class_register_static_method); + methods = rb_obj_protected_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "singleton_method", methods, &class_register_static_method); - methods = rb_obj_private_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "singleton_method", methods, &class_register_static_method); + methods = rb_obj_private_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "singleton_method", methods, &class_register_static_method); #else - methods = rb_obj_singleton_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "singleton_method", methods, &class_register_static_method); + methods = rb_obj_singleton_methods(1, argv, cls); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "method", methods, &class_register_static_method); #endif - /* Discover attributes */ - VALUE static_attributes = rb_mod_class_variables(1, argv, cls); - rb_loader_impl_discover_attributes(c, class_name_str, static_attributes, &class_register_static_attribute); - - VALUE instance_attributes = rb_obj_instance_variables(cls); - rb_loader_impl_discover_attributes(c, class_name_str, instance_attributes, &class_register_attribute); - - /* Define default constructor. Ruby only supports one constructor, a - * method called 'initialize'. It can have arguments but when inspected via - * reflection, the signature is variadic arguments and cannot be inspected: - * - * MyClass.methods(:initialize).parameters = [[:rest]] # variadic args notation in Ruby - * - * Due to this, we will always register only one default constructor without arguments - * which will take all the arguments when invoking 'new' and apply them as variadic. - */ - constructor ctor = constructor_create(0, VISIBILITY_PUBLIC); - - if (class_register_constructor(c, ctor) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Failed to register default constructor in class %s", class_name_str); - } + /* Discover attributes */ + VALUE static_attributes = rb_mod_class_variables(1, argv, cls); + rb_loader_impl_discover_attributes(c, class_name_str, static_attributes, &class_register_static_attribute); + + VALUE instance_attributes = rb_obj_instance_variables(cls); + rb_loader_impl_discover_attributes(c, class_name_str, instance_attributes, &class_register_attribute); + + /* Define default constructor. Ruby only supports one constructor, a + * method called 'initialize'. It can have arguments but when inspected via + * reflection, the signature is variadic arguments and cannot be inspected: + * + * MyClass.methods(:initialize).parameters = [[:rest]] # variadic args notation in Ruby + * + * Due to this, we will always register only one default constructor without arguments + * which will take all the arguments when invoking 'new' and apply them as variadic. + */ + constructor ctor = constructor_create(0, VISIBILITY_PUBLIC); + + if (class_register_constructor(c, ctor) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to register default constructor in class %s", class_name_str); + } - scope sp = context_scope(ctx); - value v = value_create_class(c); + scope sp = context_scope(ctx); + value v = value_create_class(c); - if (scope_define(sp, class_name_str, v) != 0) - { - value_type_destroy(v); - return 1; - } + if (scope_define(sp, class_name_str, v) != 0) + { + value_type_destroy(v); + return INT2NUM(1); } } } - return 0; + return INT2NUM(0); +} + +int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_module, context ctx) +{ + struct loader_impl_rb_discover_module_protect_type protect; + int state; + VALUE result; + + log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader discovering:"); + + if (rb_module->empty == 0) + { + return 0; + } + + protect.impl = impl; + protect.rb_module = rb_module; + protect.ctx = ctx; + + result = rb_protect(rb_loader_impl_discover_module_protect, (VALUE)&protect, &state); + + if (state != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby module discover failed"); + rb_loader_impl_print_exception(); + return 1; + } + + return NUM2INT(result); } int rb_loader_impl_discover(loader_impl impl, loader_handle handle, context ctx) diff --git a/source/loaders/rb_loader/source/rb_loader_port.c b/source/loaders/rb_loader/source/rb_loader_port.c index 0b3b97c7a..18f957f0d 100644 --- a/source/loaders/rb_loader/source/rb_loader_port.c +++ b/source/loaders/rb_loader/source/rb_loader_port.c @@ -29,7 +29,7 @@ static loader_impl rb_loader_impl = NULL; -VALUE rb_loader_port_load_from_file(VALUE self, VALUE tag_value, VALUE paths_value) +static VALUE rb_loader_port_load_from_file(VALUE self, VALUE tag_value, VALUE paths_value) { const char *tag; const char **paths; @@ -96,7 +96,7 @@ VALUE rb_loader_port_load_from_file(VALUE self, VALUE tag_value, VALUE paths_val return LONG2NUM(result); } -VALUE rb_loader_port_load_from_memory(VALUE self, VALUE tag_value, VALUE buffer_value) +static VALUE rb_loader_port_load_from_memory(VALUE self, VALUE tag_value, VALUE buffer_value) { const char *tag; const char *buffer; @@ -138,7 +138,7 @@ VALUE rb_loader_port_load_from_memory(VALUE self, VALUE tag_value, VALUE buffer_ return LONG2NUM(result); } -VALUE rb_loader_port_metacall(int argc, VALUE *argv, VALUE self) +static VALUE rb_loader_port_metacall(int argc, VALUE *argv, VALUE self) { const char *function_name; size_t args_size, iterator; @@ -195,7 +195,7 @@ VALUE rb_loader_port_metacall(int argc, VALUE *argv, VALUE self) return rb_type_serialize(result); } -VALUE rb_loader_port_inspect(VALUE self) +static VALUE rb_loader_port_inspect(VALUE self) { VALUE result; size_t size = 0; @@ -232,6 +232,22 @@ VALUE rb_loader_port_inspect(VALUE self) return result; } +static VALUE rb_loader_port_atexit(VALUE self) +{ + static int atexit_executed = 0; + + (void)self; + + if (atexit_executed == 0 && rb_loader_impl_destroy(rb_loader_impl) != 0) + { + rb_raise(rb_eSystemExit, "Failed to destroy Ruby Loader from MetaCall"); + } + + atexit_executed = 1; + + return Qnil; +} + int rb_loader_port_initialize(loader_impl impl) { VALUE rb_loader_port; @@ -251,6 +267,7 @@ int rb_loader_port_initialize(loader_impl impl) rb_define_module_function(rb_loader_port, "metacall_load_from_memory", rb_loader_port_load_from_memory, 2); rb_define_module_function(rb_loader_port, "metacall", rb_loader_port_metacall, -1); rb_define_module_function(rb_loader_port, "metacall_inspect", rb_loader_port_inspect, 0); + rb_define_module_function(rb_loader_port, "rb_loader_port_atexit", rb_loader_port_atexit, 0); rb_loader_impl = impl; diff --git a/source/ports/rb_port/package/lib/metacall.rb b/source/ports/rb_port/package/lib/metacall.rb index ba36cea95..f54e37ca5 100644 --- a/source/ports/rb_port/package/lib/metacall.rb +++ b/source/ports/rb_port/package/lib/metacall.rb @@ -99,6 +99,8 @@ def metacall_module_load # Check again if the port was loaded if defined?(MetaCallRbLoaderPort) + + return MetaCallRbLoaderPort else raise LoadError, 'MetaCall was found but failed to load MetaCallRbLoaderPort' @@ -108,6 +110,28 @@ def metacall_module_load # Initialize the MetaCall Ruby Port metacall_module_load + # When we are running MetaCall with Ruby, we should hook the at exit method + if ENV.key?('METACALL_HOST') + module Kernel + alias_method :original_exit, :exit + alias_method :original_exit_bang, :exit! + + def exit(status = true) + if defined?(MetaCallRbLoaderPort) && MetaCall.respond_to?(:rb_loader_port_atexit) + MetaCallRbLoaderPort.rb_loader_port_atexit + end + original_exit(status) + end + + def exit!(status = true) + if defined?(MetaCallRbLoaderPort) && MetaCall.respond_to?(:rb_loader_port_atexit) + MetaCallRbLoaderPort.rb_loader_port_atexit + end + original_exit_bang(status) + end + end + end + public def metacall_load_from_file(tag, paths) From 4eea25b2dc58b6013db3061e0d0339d13e375ab9 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Fri, 20 Jun 2025 17:21:58 +0200 Subject: [PATCH 015/109] Solve issues with ruby. --- .../loaders/rb_loader/source/rb_loader_impl.c | 166 ++++++++++++------ source/ports/rb_port/package/lib/metacall.rb | 2 - source/scripts/ruby/klass/source/klass.rb | 2 - 3 files changed, 109 insertions(+), 61 deletions(-) diff --git a/source/loaders/rb_loader/source/rb_loader_impl.c b/source/loaders/rb_loader/source/rb_loader_impl.c index 325844066..9d0e43afb 100644 --- a/source/loaders/rb_loader/source/rb_loader_impl.c +++ b/source/loaders/rb_loader/source/rb_loader_impl.c @@ -968,7 +968,12 @@ loader_impl_data rb_loader_impl_initialize(loader_impl impl, configuration confi ruby_init(); - ruby_init_loadpath(); + /* Apparently ruby_init_loadpath is not enough to initialize the builtins and gems, + * so we use ruby_options instead + */ + /* ruby_init_loadpath(); */ + + ruby_options(argc, argv); } if (rb_loader_impl_initialize_types(impl) != 0) @@ -1098,7 +1103,7 @@ VALUE rb_loader_impl_module_eval_protect(VALUE args) return rb_mod_module_eval(protect->argc, protect->argv, protect->module); } -void rb_loader_impl_print_exception(void) +static void rb_loader_impl_print_exception(void) { VALUE exception = rb_gv_get("$!"); @@ -1262,12 +1267,43 @@ loader_handle rb_loader_impl_load_from_file(loader_impl impl, const loader_path { #define rb_str_new_static_size(str) rb_str_new_static(str, sizeof(str) - 1) - VALUE wrapped_code = rb_str_new_static_size("require 'rubygems'\n"); + static const char header[] = + /* AtExitInterceptor is needed due to Ruby's nature, it calls + * at_exit during ruby_cleanup and due to this, scripts depending on + * this feature like unit tests will run after MetaCall has started + * to destroy the objects of reflect associated to the loader. + * In order to avoid this, we hook into at_exit and we execute at + * the end of the main script execution. + */ + "module AtExitInterceptor\n" + " @captured_exit_procs = []\n" + " def self.captured_exit_procs\n" + " @captured_exit_procs\n" + " end\n" + /* Replace Kernel.at_exit */ + " module ::Kernel\n" + " alias_method :__original_at_exit, :at_exit\n" + " def at_exit(&block)\n" + " AtExitInterceptor.captured_exit_procs << block\n" + " nil\n" + " end\n" + " end\n" + /* Manual runner */ + " def self.run_all\n" + /* Run in reverse order to match Ruby's actual behavior */ + " @captured_exit_procs.reverse_each do |proc|\n" + " proc.call\n" + " end\n" + " end\n" + "end\n"; + + VALUE wrapped_code = rb_str_new_static_size(header); wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("module ")); wrapped_code = rb_str_plus(wrapped_code, module_name); wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("\n")); wrapped_code = rb_str_plus(wrapped_code, module_data); - wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("\nend")); + wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("\nend\n")); + wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("AtExitInterceptor.run_all\n")); #undef rb_str_new_static_size @@ -1278,9 +1314,28 @@ loader_handle rb_loader_impl_load_from_file(loader_impl impl, const loader_path if (state != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "Ruby evaluation failed %s", paths[0]); - rb_loader_impl_print_exception(); - goto load_error; + VALUE err = rb_errinfo(); + VALUE system_exit_class = rb_const_get(rb_cObject, rb_intern("SystemExit")); + + /* Check if the script exited */ + if (rb_obj_is_kind_of(err, system_exit_class)) + { + VALUE status = rb_funcall(err, rb_intern("status"), 0); + int exit_status = NUM2INT(status); + + if (exit_status != 0) + { + exit(exit_status); + } + + rb_set_errinfo(Qnil); + } + else + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby evaluation failed %s", paths[0]); + rb_loader_impl_print_exception(); + goto load_error; + } } /* Get the module reference */ @@ -1518,61 +1573,58 @@ void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_ VALUE name = rb_sym2str(rb_method); const char *method_name_str = RSTRING_PTR(name); - if (rb_respond_to(cls, RB_SYM2ID(rb_method))) - { - VALUE instance_method = rb_funcall(cls, rb_intern(method_type_str), 1, rb_method); - VALUE parameters = rb_funcallv(instance_method, rb_intern("parameters"), 0, NULL); - size_t args_it, args_count = RARRAY_LEN(parameters); + VALUE instance_method = rb_funcall(cls, rb_intern(method_type_str), 1, rb_method); + VALUE parameters = rb_funcallv(instance_method, rb_intern("parameters"), 0, NULL); + size_t args_it, args_count = RARRAY_LEN(parameters); - log_write("metacall", LOG_LEVEL_DEBUG, "Method '%s' inside '%s' of type %s with %" PRIuS " parameters", method_name_str, class_name_str, method_type_str, args_count); + log_write("metacall", LOG_LEVEL_DEBUG, "Method '%s' inside '%s' of type %s with %" PRIuS " parameters", method_name_str, class_name_str, method_type_str, args_count); - /* - * TODO: - * Another alternative (for supporting types), which is not used in the current implementation, - * but it can simplify the parser, it's the following: - * - * - For classes: origin_file, definition_line = MyClass.instance_method(:foo).source_location - * - For plain functions: origin_file, definition_line = method(:foo).source_location - * - * Then: - * method_signature = IO.readlines(origin_file)[definition_line.pred] - * - * Now we have only the method signature, this is going to be less problematic than parsing - * the whole file as we are doing now (although for multi-line signatures it's going to be - * a little bit more complicated...) - * - * We can switch to completely duck typed approach (refactoring the tests) or we can use this - * simplified parsing approach and maintain types - */ + /* + * TODO: + * Another alternative (for supporting types), which is not used in the current implementation, + * but it can simplify the parser, it's the following: + * + * - For classes: origin_file, definition_line = MyClass.instance_method(:foo).source_location + * - For plain functions: origin_file, definition_line = method(:foo).source_location + * + * Then: + * method_signature = IO.readlines(origin_file)[definition_line.pred] + * + * Now we have only the method signature, this is going to be less problematic than parsing + * the whole file as we are doing now (although for multi-line signatures it's going to be + * a little bit more complicated...) + * + * We can switch to completely duck typed approach (refactoring the tests) or we can use this + * simplified parsing approach and maintain types + */ - method m = method_create(c, - method_name_str, - args_count, - (method_impl)instance_method, - visibility, - SYNCHRONOUS, /* There is not async functions in Ruby */ - NULL); + method m = method_create(c, + method_name_str, + args_count, + (method_impl)instance_method, + visibility, + SYNCHRONOUS, /* There is not async functions in Ruby */ + NULL); - signature s = method_signature(m); + signature s = method_signature(m); - for (args_it = 0; args_it < args_count; ++args_it) - { - VALUE parameter_pair = rb_ary_entry(parameters, args_it); + for (args_it = 0; args_it < args_count; ++args_it) + { + VALUE parameter_pair = rb_ary_entry(parameters, args_it); - if (RARRAY_LEN(parameter_pair) == 2) - { - VALUE parameter_name_id = rb_ary_entry(parameter_pair, 1); - VALUE parameter_name = rb_sym2str(parameter_name_id); - const char *parameter_name_str = RSTRING_PTR(parameter_name); + if (RARRAY_LEN(parameter_pair) == 2) + { + VALUE parameter_name_id = rb_ary_entry(parameter_pair, 1); + VALUE parameter_name = rb_sym2str(parameter_name_id); + const char *parameter_name_str = RSTRING_PTR(parameter_name); - signature_set(s, args_it, parameter_name_str, NULL); - } + signature_set(s, args_it, parameter_name_str, NULL); } + } - if (register_method(c, m) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Ruby failed to register method '%s' in class '%s'", method_name_str, class_name_str); - } + if (register_method(c, m) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby failed to register method '%s' in class '%s'", method_name_str, class_name_str); } } } @@ -1680,7 +1732,7 @@ static VALUE rb_loader_impl_discover_module_protect(VALUE args) rb_cls->impl = impl; /* Discover methods */ - VALUE argv[1] = { Qtrue }; /* include_superclasses ? Qtrue : Qfalse; */ + VALUE argv[1] = { Qfalse /* include_superclasses ? Qtrue : Qfalse; */ }; VALUE methods = rb_class_public_instance_methods(1, argv, cls); /* argc, argv, cls */ rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "instance_method", methods, &class_register_method); @@ -1692,13 +1744,13 @@ static VALUE rb_loader_impl_discover_module_protect(VALUE args) #if RUBY_VERSION_MAJOR == 3 && RUBY_VERSION_MINOR >= 0 methods = rb_obj_public_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "singleton_method", methods, &class_register_static_method); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "method", methods, &class_register_static_method); methods = rb_obj_protected_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "singleton_method", methods, &class_register_static_method); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PROTECTED, "method", methods, &class_register_static_method); methods = rb_obj_private_methods(1, argv, cls); - rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "singleton_method", methods, &class_register_static_method); + rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PRIVATE, "method", methods, &class_register_static_method); #else methods = rb_obj_singleton_methods(1, argv, cls); rb_loader_impl_discover_methods(c, cls, class_name_str, VISIBILITY_PUBLIC, "method", methods, &class_register_static_method); diff --git a/source/ports/rb_port/package/lib/metacall.rb b/source/ports/rb_port/package/lib/metacall.rb index f54e37ca5..e889f03ea 100644 --- a/source/ports/rb_port/package/lib/metacall.rb +++ b/source/ports/rb_port/package/lib/metacall.rb @@ -99,8 +99,6 @@ def metacall_module_load # Check again if the port was loaded if defined?(MetaCallRbLoaderPort) - - return MetaCallRbLoaderPort else raise LoadError, 'MetaCall was found but failed to load MetaCallRbLoaderPort' diff --git a/source/scripts/ruby/klass/source/klass.rb b/source/scripts/ruby/klass/source/klass.rb index ad37a4573..86e392930 100644 --- a/source/scripts/ruby/klass/source/klass.rb +++ b/source/scripts/ruby/klass/source/klass.rb @@ -39,6 +39,4 @@ def return_class_function() return MyClass end - #p return_class_function()::CLASS_CONSTANT - From a58272041baba227dc2ee44344d9e12038f0efee Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Fri, 20 Jun 2025 17:22:17 +0200 Subject: [PATCH 016/109] Solve issues with debug prints on python. --- .../loaders/py_loader/source/py_loader_impl.c | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/source/loaders/py_loader/source/py_loader_impl.c b/source/loaders/py_loader/source/py_loader_impl.c index a5fa1d9ff..dcf5ab92a 100644 --- a/source/loaders/py_loader/source/py_loader_impl.c +++ b/source/loaders/py_loader/source/py_loader_impl.c @@ -54,6 +54,12 @@ #define DEBUG_ENABLED 0 #endif +/* Set this variable to 1 in order to debug garbage collection data +* and threading flow for improving the debug of memory leaks and async bugs. +* Set it to 0 in order to remove all the noise. +*/ +#define DEBUG_PRINT_ENABLED 1 + typedef struct loader_impl_py_function_type { PyObject *func; @@ -160,7 +166,7 @@ static value py_loader_impl_error_value(loader_impl_py py_impl); static value py_loader_impl_error_value_from_exception(loader_impl_py py_impl, PyObject *type_obj, PyObject *value_obj, PyObject *traceback_obj); -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED #if (defined(__ADDRESS_SANITIZER__) || defined(__MEMORY_SANITIZER__)) static void py_loader_impl_gc_print(loader_impl_py py_impl); #endif @@ -2221,7 +2227,7 @@ int py_loader_impl_initialize_traceback(loader_impl impl, loader_impl_py py_impl return 1; } -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED int py_loader_impl_initialize_gc(loader_impl_py py_impl) { PyObject *flags; @@ -2396,10 +2402,10 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) "import asyncio\n" "import threading\n" "import sys\n" -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED "def trace_calls(frame, event, arg):\n" " t = threading.current_thread()\n" - " print(f\"[{t.native_id}] {t.name}: {event} {frame.f_code.co_name}\")\n" + " print(f\"[{t.native_id}] {t.name}: {event} {frame.f_code.co_name}\", flush=True)\n" "threading.settrace(trace_calls)\n" "sys.settrace(trace_calls)\n" #endif @@ -2686,7 +2692,7 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi loader_impl_py py_impl = malloc(sizeof(struct loader_impl_py_type)); int traceback_initialized = 1; -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED int gc_initialized = 1; #endif int gil_release; @@ -2762,7 +2768,7 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi traceback_initialized = 0; } -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED /* Initialize GC module */ { gc_initialized = py_loader_impl_initialize_gc(py_impl); @@ -2862,7 +2868,7 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi Py_DecRef(py_impl->traceback_format_exception); Py_DecRef(py_impl->traceback_module); } -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED if (gc_initialized == 0) { Py_DecRef(py_impl->gc_set_debug); @@ -2917,7 +2923,7 @@ int py_loader_impl_execution_path(loader_impl impl, const loader_path path) goto clear_current_path; } -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED py_loader_impl_sys_path_print(system_paths); #endif @@ -4199,7 +4205,7 @@ value py_loader_impl_error_value_from_exception(loader_impl_py py_impl, PyObject return ret; } -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED #if (defined(__ADDRESS_SANITIZER__) || defined(__MEMORY_SANITIZER__)) void py_loader_impl_gc_print(loader_impl_py py_impl) { @@ -4355,7 +4361,7 @@ int py_loader_impl_destroy(loader_impl impl) Py_DecRef(py_impl->thread_background_stop); Py_DecRef(py_impl->thread_background_register_atexit); -#if DEBUG_ENABLED +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED { #if (defined(__ADDRESS_SANITIZER__) || defined(__MEMORY_SANITIZER__)) py_loader_impl_gc_print(py_impl); From d8e061b17c2a4eebe8a4e9fbebbc876ec58a7e75 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 1 Jul 2025 08:05:21 +0200 Subject: [PATCH 017/109] Solve issues with deadlocks on windows. --- .../loaders/py_loader/source/py_loader_impl.c | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/source/loaders/py_loader/source/py_loader_impl.c b/source/loaders/py_loader/source/py_loader_impl.c index dcf5ab92a..d5a11d618 100644 --- a/source/loaders/py_loader/source/py_loader_impl.c +++ b/source/loaders/py_loader/source/py_loader_impl.c @@ -4302,6 +4302,80 @@ int py_loader_impl_finalize(loader_impl_py py_impl, const int host) return 0; } +#if defined(WIN32) || defined(_WIN32) +/* On Windows, threads are destroyed when atexit is executed, we should control this in order to avoid deadlocks */ +static long py_loader_impl_asyncio_thread_native_id(loader_impl_py py_impl) +{ + PyObject *thread_obj = PyObject_GetAttrString(py_impl->asyncio_loop, "t"); + + if (thread_obj == NULL) + { + return -1; + } + + PyObject *native_id_obj = PyObject_GetAttrString(thread_obj, "native_id"); + Py_DecRef(thread_obj); + + if (thread_obj == NULL) + { + return -1; + } + + long native_id = PyLong_AsLong(native_id_obj); + Py_DecRef(native_id_obj); + + if (PyErr_Occurred()) + { + py_loader_impl_error_print(py_impl); + return -1; + } + + return native_id; +} + +static int py_loader_impl_check_thread(loader_impl_py py_impl) +{ + long thread_id = py_loader_impl_asyncio_thread_native_id(py_impl); + + if (thread_id == -1) + { + return -1; + } + + HANDLE thread_handle = OpenThread(THREAD_QUERY_INFORMATION | SYNCHRONIZE, FALSE, thread_id); + + if (thread_handle == NULL) + { + return 1; + } + + DWORD result = WaitForSingleObject(thread_handle, 0); + + CloseHandle(thread_handle); + + if (result == WAIT_TIMEOUT) + { + return 0; + } + else if (result == WAIT_OBJECT_0) + { + /* This workaround forces to skip thread waiting, so it avoids deadlocks */ + PyObject *sys_modules = PyImport_GetModuleDict(); + + if (PyDict_DelItemString(sys_modules, "threading") < 0) + { + PyErr_Print(); + } + + return 1; + } + else + { + return -1; + } +} +#endif + int py_loader_impl_destroy(loader_impl impl) { const int host = loader_impl_get_option_host(impl); @@ -4319,6 +4393,9 @@ int py_loader_impl_destroy(loader_impl impl) py_loader_thread_acquire(); /* Stop event loop for async calls */ +#if defined(WIN32) || defined(_WIN32) + if (py_loader_impl_check_thread(py_impl) == 0) +#endif { PyObject *args_tuple = PyTuple_New(2); Py_IncRef(py_impl->asyncio_loop); From 1cc1a3cb086ab9e3815b874816687f6d7dc16fda Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 1 Jul 2025 08:33:13 +0200 Subject: [PATCH 018/109] Solve issues with wasmtime. --- .../loaders/wasm_loader/source/wasm_loader_impl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/loaders/wasm_loader/source/wasm_loader_impl.c b/source/loaders/wasm_loader/source/wasm_loader_impl.c index 558ea0215..d359ef872 100644 --- a/source/loaders/wasm_loader/source/wasm_loader_impl.c +++ b/source/loaders/wasm_loader/source/wasm_loader_impl.c @@ -18,6 +18,13 @@ * */ +#ifdef WASMTIME + #if defined(_WIN32) && defined(_MSC_VER) + #define WASM_API_EXTERN + #endif + #include +#endif + #include #include #include @@ -35,13 +42,6 @@ #include -#ifdef WASMTIME - #if defined(_WIN32) && defined(_MSC_VER) - #define WASM_API_EXTERN - #endif - #include -#endif - #define COUNT_OF(array) (sizeof(array) / sizeof(array[0])) typedef struct loader_impl_wasm_type From 33220069d4cefeb098f35b258506d7717e252a37 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 1 Jul 2025 08:39:39 +0200 Subject: [PATCH 019/109] Update version to v0.9.10. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6f060dcbc..ea8f4fd66 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.9 \ No newline at end of file +0.9.10 \ No newline at end of file From cd0348f8f22209ff51ac375ab47bded5895292a1 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Tue, 1 Jul 2025 22:24:38 +0200 Subject: [PATCH 020/109] Solve issues with macos ci. --- .github/workflows/macos-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos-test.yml b/.github/workflows/macos-test.yml index d6ba0dc3b..2a5725996 100644 --- a/.github/workflows/macos-test.yml +++ b/.github/workflows/macos-test.yml @@ -110,7 +110,7 @@ jobs: workflow_file_name: test.yml wait_workflow: true client_payload: '{"ref": "${{ github.head_ref || github.ref_name }}"}' - ref: ${{ github.head_ref || github.ref_name }} + ref: main - name: MacOS Workflow Dispatch uses: convictional/trigger-workflow-and-wait@v1.6.1 with: From 73c020e0188434705d5308ac2e7e83f94c0138fd Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 00:41:46 +0200 Subject: [PATCH 021/109] Improve python package publish and add nodejs package publish. --- .github/workflows/release-nodejs.yml | 26 ++++++++++++++++++++++++++ source/ports/node_port/upload.sh | 22 +++++++++++++++++++--- source/ports/py_port/VERSION | 2 +- source/ports/py_port/upload.sh | 3 +-- 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/release-nodejs.yml diff --git a/.github/workflows/release-nodejs.yml b/.github/workflows/release-nodejs.yml new file mode 100644 index 000000000..1f82be6da --- /dev/null +++ b/.github/workflows/release-nodejs.yml @@ -0,0 +1,26 @@ +name: Release NodeJS Package + +on: + push: + branches: [ master, develop ] + paths: + - 'source/ports/node_port/package.json' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + release: + name: Release NodeJS Port + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Release the port + working-directory: source/ports/node_port + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: ./upload.sh diff --git a/source/ports/node_port/upload.sh b/source/ports/node_port/upload.sh index a38301bd8..664e4b83c 100755 --- a/source/ports/node_port/upload.sh +++ b/source/ports/node_port/upload.sh @@ -19,8 +19,24 @@ # limitations under the License. # -# TODO: Update version in package.json -# TODO: Automate for CD/CI +set -euxo pipefail + +NPM_VERSION=$(npm view metacall version) +PORT_VERSION=$(node -p "require('./package.json').version") + +if [[ "$NPM_VERSION" == "$PORT_VERSION" ]]; then + echo "Current package version is the same as NPM version, skipping upload." + exit 0 +fi + +if [[ -z "${NPM_TOKEN:-}" ]]; then + echo "NPM_TOKEN environment variable is not set or empty, skipping upload" + exit 1 +fi + +# Register the token +echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc # Publish -npm login && npm publish +npm login +npm publish diff --git a/source/ports/py_port/VERSION b/source/ports/py_port/VERSION index 5d4294b91..2411653a5 100644 --- a/source/ports/py_port/VERSION +++ b/source/ports/py_port/VERSION @@ -1 +1 @@ -0.5.1 \ No newline at end of file +0.5.2 \ No newline at end of file diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index 5e8635432..c1505e7c3 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -30,8 +30,7 @@ if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then fi # Install dependencies and upload MetaCall package -python3 -m pip install --user --upgrade twine setuptools wheel # build -# python3 -m build +python3 -m pip install --user --upgrade twine setuptools wheel python3 setup.py sdist bdist_wheel python3 -m twine check dist/* python3 -m twine upload dist/* From 695a79985bf71f4972c20725717cdf070a109166 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 00:48:08 +0200 Subject: [PATCH 022/109] Trying to solve more issues in node and python packages. --- .github/workflows/release-nodejs.yml | 2 +- .github/workflows/release-python.yml | 2 +- source/ports/py_port/setup.cfg | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-nodejs.yml b/.github/workflows/release-nodejs.yml index 1f82be6da..da626217c 100644 --- a/.github/workflows/release-nodejs.yml +++ b/.github/workflows/release-nodejs.yml @@ -4,7 +4,7 @@ on: push: branches: [ master, develop ] paths: - - 'source/ports/node_port/package.json' + - 'source/ports/node_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/release-python.yml b/.github/workflows/release-python.yml index 52f6f4c88..d2d96cabd 100644 --- a/.github/workflows/release-python.yml +++ b/.github/workflows/release-python.yml @@ -4,7 +4,7 @@ on: push: branches: [ master, develop ] paths: - - 'source/ports/py_port/VERSION' + - 'source/ports/py_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/source/ports/py_port/setup.cfg b/source/ports/py_port/setup.cfg index 79bc67848..6a92005e2 100644 --- a/source/ports/py_port/setup.cfg +++ b/source/ports/py_port/setup.cfg @@ -3,3 +3,6 @@ # 3. If at all possible, it is good practice to do this. If you cannot, you # will need to generate wheels for each Python version that you support. universal=1 + +[metadata] +license_files=LICENSE.txt From 44395aec234bb8d73cae2813027f09fe07fc57cb Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 00:55:04 +0200 Subject: [PATCH 023/109] Solve issues with python. --- source/ports/py_port/setup.cfg | 1 + source/ports/py_port/setup.py | 3 --- source/ports/py_port/upload.sh | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/ports/py_port/setup.cfg b/source/ports/py_port/setup.cfg index 6a92005e2..cc49de877 100644 --- a/source/ports/py_port/setup.cfg +++ b/source/ports/py_port/setup.cfg @@ -5,4 +5,5 @@ universal=1 [metadata] +license=Apache-2.0 license_files=LICENSE.txt diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index 4841636e9..bda3e96c8 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -71,9 +71,6 @@ 'Intended Audience :: Developers', 'Topic :: Software Development :: Interpreters', - # License - 'License :: OSI Approved :: Apache Software License', - # Python versions support #'Programming Language :: Python :: 2', #'Programming Language :: Python :: 2.6', diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index c1505e7c3..d3ff9f3e2 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -30,7 +30,8 @@ if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then fi # Install dependencies and upload MetaCall package -python3 -m pip install --user --upgrade twine setuptools wheel +python3 -m pip install --user --upgrade twine setuptools wheel build +python3 -m build python3 setup.py sdist bdist_wheel python3 -m twine check dist/* python3 -m twine upload dist/* From 3a47ed3f3e006bbc80a0e8f7a323e4ae24f4a036 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 00:57:22 +0200 Subject: [PATCH 024/109] Remove python build. --- source/ports/py_port/upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index d3ff9f3e2..01e368666 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -31,7 +31,7 @@ fi # Install dependencies and upload MetaCall package python3 -m pip install --user --upgrade twine setuptools wheel build -python3 -m build +# python3 -m build python3 setup.py sdist bdist_wheel python3 -m twine check dist/* python3 -m twine upload dist/* From 2f6a01045ef5fc81c1bbc90524481d168f2a4ed1 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 06:48:37 +0200 Subject: [PATCH 025/109] Update python port. --- source/ports/py_port/README.rst | 4 ++-- source/ports/py_port/metacall/__init__.py | 2 +- source/ports/py_port/metacall/{api.py => metacall.py} | 0 source/ports/py_port/setup.cfg | 6 ------ 4 files changed, 3 insertions(+), 9 deletions(-) rename source/ports/py_port/metacall/{api.py => metacall.py} (100%) diff --git a/source/ports/py_port/README.rst b/source/ports/py_port/README.rst index c90d8c46b..27c27ab53 100644 --- a/source/ports/py_port/README.rst +++ b/source/ports/py_port/README.rst @@ -25,7 +25,7 @@ Then install MetaCall Python package through MetaCall: .. code:: console - metacall pip3 install metacall + pip3 install metacall Example ======= @@ -55,7 +55,7 @@ Running the example: .. code:: console - metacall main.py + python3 main.py Using pointers (calling to a C library) --------------------------------------- diff --git a/source/ports/py_port/metacall/__init__.py b/source/ports/py_port/metacall/__init__.py index 412cd2dd1..e34d69bc5 100644 --- a/source/ports/py_port/metacall/__init__.py +++ b/source/ports/py_port/metacall/__init__.py @@ -17,4 +17,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -from metacall.api import metacall, metacall_load_from_file, metacall_load_from_memory, metacall_load_from_package, metacall_inspect, metacall_value_create_ptr, metacall_value_reference, metacall_value_dereference +from metacall.metacall import metacall, metacall_load_from_file, metacall_load_from_memory, metacall_load_from_package, metacall_inspect, metacall_value_create_ptr, metacall_value_reference, metacall_value_dereference diff --git a/source/ports/py_port/metacall/api.py b/source/ports/py_port/metacall/metacall.py similarity index 100% rename from source/ports/py_port/metacall/api.py rename to source/ports/py_port/metacall/metacall.py diff --git a/source/ports/py_port/setup.cfg b/source/ports/py_port/setup.cfg index cc49de877..51402097a 100644 --- a/source/ports/py_port/setup.cfg +++ b/source/ports/py_port/setup.cfg @@ -1,9 +1,3 @@ -[bdist_wheel] -# This flag says that the code is written to work on both Python 2 and Python -# 3. If at all possible, it is good practice to do this. If you cannot, you -# will need to generate wheels for each Python version that you support. -universal=1 - [metadata] license=Apache-2.0 license_files=LICENSE.txt From 4eb5d8cb4c9f1a2f2404ebf83e41723c5553b208 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 06:49:39 +0200 Subject: [PATCH 026/109] Testing node port. --- .github/workflows/release-nodejs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-nodejs.yml b/.github/workflows/release-nodejs.yml index da626217c..bc733d613 100644 --- a/.github/workflows/release-nodejs.yml +++ b/.github/workflows/release-nodejs.yml @@ -3,8 +3,8 @@ name: Release NodeJS Package on: push: branches: [ master, develop ] - paths: - - 'source/ports/node_port/**' + # paths: + # - 'source/ports/node_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From 7059976e5dcfa3ec2f4b577a414d865f6a6fc538 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 06:53:02 +0200 Subject: [PATCH 027/109] Trying to build python package. --- source/ports/py_port/metacall/__init__.py | 2 +- source/ports/py_port/metacall/{metacall.py => api.py} | 0 source/ports/py_port/upload.sh | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename source/ports/py_port/metacall/{metacall.py => api.py} (100%) diff --git a/source/ports/py_port/metacall/__init__.py b/source/ports/py_port/metacall/__init__.py index e34d69bc5..412cd2dd1 100644 --- a/source/ports/py_port/metacall/__init__.py +++ b/source/ports/py_port/metacall/__init__.py @@ -17,4 +17,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -from metacall.metacall import metacall, metacall_load_from_file, metacall_load_from_memory, metacall_load_from_package, metacall_inspect, metacall_value_create_ptr, metacall_value_reference, metacall_value_dereference +from metacall.api import metacall, metacall_load_from_file, metacall_load_from_memory, metacall_load_from_package, metacall_inspect, metacall_value_create_ptr, metacall_value_reference, metacall_value_dereference diff --git a/source/ports/py_port/metacall/metacall.py b/source/ports/py_port/metacall/api.py similarity index 100% rename from source/ports/py_port/metacall/metacall.py rename to source/ports/py_port/metacall/api.py diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index 01e368666..d3ff9f3e2 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -31,7 +31,7 @@ fi # Install dependencies and upload MetaCall package python3 -m pip install --user --upgrade twine setuptools wheel build -# python3 -m build +python3 -m build python3 setup.py sdist bdist_wheel python3 -m twine check dist/* python3 -m twine upload dist/* From 5b8ddaa46e8b820295707af423607d8076c52db5 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 06:54:41 +0200 Subject: [PATCH 028/109] Corrected bash script. --- source/ports/node_port/upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/node_port/upload.sh b/source/ports/node_port/upload.sh index 664e4b83c..f37d4c53a 100755 --- a/source/ports/node_port/upload.sh +++ b/source/ports/node_port/upload.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # # MetaCall NodeJS Port Deploy Script by Parra Studios From 050a199baaaf9b952f1d6e7c54e56557a1277e84 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 06:57:45 +0200 Subject: [PATCH 029/109] Update version of node package. --- .github/workflows/release-nodejs.yml | 4 ++-- source/ports/node_port/package-lock.json | 2 +- source/ports/node_port/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-nodejs.yml b/.github/workflows/release-nodejs.yml index bc733d613..da626217c 100644 --- a/.github/workflows/release-nodejs.yml +++ b/.github/workflows/release-nodejs.yml @@ -3,8 +3,8 @@ name: Release NodeJS Package on: push: branches: [ master, develop ] - # paths: - # - 'source/ports/node_port/**' + paths: + - 'source/ports/node_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/source/ports/node_port/package-lock.json b/source/ports/node_port/package-lock.json index bfb3b0d1b..33e7e61c0 100644 --- a/source/ports/node_port/package-lock.json +++ b/source/ports/node_port/package-lock.json @@ -1,6 +1,6 @@ { "name": "metacall", - "version": "0.5.0", + "version": "0.5.1", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/source/ports/node_port/package.json b/source/ports/node_port/package.json index f9508ef75..5c15efc0b 100644 --- a/source/ports/node_port/package.json +++ b/source/ports/node_port/package.json @@ -1,6 +1,6 @@ { "name": "metacall", - "version": "0.5.0", + "version": "0.5.1", "description": "Call Python, C#, Ruby... functions from NodeJS (a NodeJS Port for MetaCall)", "repository": "github:metacall/core", "bugs": "https://github.com/metacall/core/issues", From ac753a400bf5415e629ed22e2df80fd9d955e3fa Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia Date: Wed, 2 Jul 2025 07:01:11 +0200 Subject: [PATCH 030/109] Update python package, remove version. --- source/ports/py_port/VERSION | 1 - source/ports/py_port/setup.py | 6 +----- source/ports/py_port/upload.sh | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 source/ports/py_port/VERSION diff --git a/source/ports/py_port/VERSION b/source/ports/py_port/VERSION deleted file mode 100644 index 2411653a5..000000000 --- a/source/ports/py_port/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.5.2 \ No newline at end of file diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index bda3e96c8..c1e17fe04 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -32,10 +32,6 @@ with open(os.path.join(current_path, 'README.rst'), encoding='utf-8') as f: long_description = f.read() -# Get the version -with open(os.path.join(current_path, 'VERSION')) as f: - version = f.read() - # Define set up options options = { 'name': 'metacall', @@ -43,7 +39,7 @@ # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html - 'version': version, + 'version': '0.5.2', 'description': 'A library for providing inter-language foreign function interface calls', 'long_description': long_description, diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index d3ff9f3e2..6aa047bb8 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -22,7 +22,7 @@ set -exuo pipefail PYPI_VERSION=$(curl -s https://pypi.org/rss/project/metacall/releases.xml | sed -n 's/\s*\([0-9.]*\).*/\1/p' | sed -n '2 p') -PORT_VERSION=$(cat VERSION) +PORT_VERSION=$(python3 setup.py --version) if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then echo "Current package version is the same as PyPI version, skipping upload." From 9499dddf3399919e8684b7172f2820d885c83409 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:04:14 +0200 Subject: [PATCH 031/109] Remove setup.py run on python package. --- source/ports/py_port/upload.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index 6aa047bb8..73a9db3ad 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -32,7 +32,6 @@ fi # Install dependencies and upload MetaCall package python3 -m pip install --user --upgrade twine setuptools wheel build python3 -m build -python3 setup.py sdist bdist_wheel python3 -m twine check dist/* python3 -m twine upload dist/* From f2b132747c0d62aaf83e658d378bcc3e6b490534 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:09:02 +0200 Subject: [PATCH 032/109] Remove setup.cfg. --- source/ports/py_port/MANIFEST.in | 4 ---- source/ports/py_port/setup.cfg | 3 --- 2 files changed, 7 deletions(-) delete mode 100644 source/ports/py_port/setup.cfg diff --git a/source/ports/py_port/MANIFEST.in b/source/ports/py_port/MANIFEST.in index 7557376f5..a4fa0c0da 100644 --- a/source/ports/py_port/MANIFEST.in +++ b/source/ports/py_port/MANIFEST.in @@ -3,7 +3,3 @@ include LICENSE.txt # Include the data files recursive-include data * - -# If using Python 2.6 or less, then have to include package data, even though -# it's already declared in setup.py -# include sample/*.dat diff --git a/source/ports/py_port/setup.cfg b/source/ports/py_port/setup.cfg deleted file mode 100644 index 51402097a..000000000 --- a/source/ports/py_port/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[metadata] -license=Apache-2.0 -license_files=LICENSE.txt From bc6deb47a64c7bf8c9075cb745b191be4afc81f9 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:11:26 +0200 Subject: [PATCH 033/109] Update license_files. --- source/ports/py_port/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index c1e17fe04..535850a82 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -54,6 +54,7 @@ # License 'license': 'Apache License 2.0', + 'license_files': 'LICENSE.txt', # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 'classifiers': [ From 9ebb3f33f3f4cfb2e4ac5cf1a4ded6ed18f76911 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:12:42 +0200 Subject: [PATCH 034/109] Update license properly. --- source/ports/py_port/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index 535850a82..ea1e15e57 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -54,7 +54,7 @@ # License 'license': 'Apache License 2.0', - 'license_files': 'LICENSE.txt', + 'license_files': ['LICENSE.txt'], # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 'classifiers': [ From f0075922a38884e8a9c653e2f1f6fa3f2c58bfda Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:16:48 +0200 Subject: [PATCH 035/109] Test python package. --- source/ports/py_port/upload.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index 73a9db3ad..a3aba92f0 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -29,6 +29,9 @@ if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then exit 0 fi +# Delete previous build +rm -rf dist build *.egg-info + # Install dependencies and upload MetaCall package python3 -m pip install --user --upgrade twine setuptools wheel build python3 -m build @@ -36,4 +39,4 @@ python3 -m twine check dist/* python3 -m twine upload dist/* # Delete output -rm -rf dist/* build/* +rm -rf dist build *.egg-info From 60242c043e86a45cd801d26642b7956728487831 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:18:00 +0200 Subject: [PATCH 036/109] Remove license files. --- source/ports/py_port/setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index ea1e15e57..c1e17fe04 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -54,7 +54,6 @@ # License 'license': 'Apache License 2.0', - 'license_files': ['LICENSE.txt'], # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 'classifiers': [ From da32696f7fbefa70800b10253a27f0f8fd02793f Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> Date: Wed, 2 Jul 2025 01:41:53 -0400 Subject: [PATCH 037/109] Create pyproject.toml --- source/ports/py_port/pyproject.toml | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 source/ports/py_port/pyproject.toml diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml new file mode 100644 index 000000000..6df32310d --- /dev/null +++ b/source/ports/py_port/pyproject.toml @@ -0,0 +1,36 @@ +[build-system] +requires = ["setuptools>=61", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "metacall" +version = "0.5.2" +description = "A library for providing inter-language foreign function interface calls" +readme = "README.rst" +requires-python = ">=3.7" +license = { text = "Apache-2.0" } +authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Topic :: Software Development :: Interpreters", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13" +] +dependencies = [] + +[tool.setuptools] +packages = ["metacall"] + +[tool.setuptools.package-data] +"metacall" = ["*"] From e857ef0f3e8f7d7a4cbfa7b754f7ec3485751cce Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:48:59 +0200 Subject: [PATCH 038/109] Improving pyproject.toml. --- source/ports/py_port/pyproject.toml | 9 +- source/ports/py_port/setup.py | 124 ---------------------------- 2 files changed, 8 insertions(+), 125 deletions(-) delete mode 100644 source/ports/py_port/setup.py diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 6df32310d..9bf127f9b 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -6,8 +6,9 @@ build-backend = "setuptools.build_meta" name = "metacall" version = "0.5.2" description = "A library for providing inter-language foreign function interface calls" +keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" -requires-python = ">=3.7" +requires-python = ">=3.3" license = { text = "Apache-2.0" } authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ @@ -29,6 +30,12 @@ classifiers = [ ] dependencies = [] +[project.urls] +Homepage = "https://metacall.io/" +Repository = "https://github.com/metacall/core" +Documentation = "https://core.metacall.io/" +Issues = "https://github.com/metacall/core/issues" + [tool.setuptools] packages = ["metacall"] diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py deleted file mode 100644 index c1e17fe04..000000000 --- a/source/ports/py_port/setup.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 - -# MetaCall Python Port by Parra Studios -# A frontend for Python language bindings in MetaCall. -# -# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# To use a consistent encoding -from codecs import open -import os -import sys -import re - -# Always prefer setuptools over distutils -from setuptools import setup, find_packages - -current_path = os.path.abspath(os.path.dirname(__file__)) - -# Get the long description from the README file -with open(os.path.join(current_path, 'README.rst'), encoding='utf-8') as f: - long_description = f.read() - -# Define set up options -options = { - 'name': 'metacall', - - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # https://packaging.python.org/en/latest/single_source_version.html - 'version': '0.5.2', - - 'description': 'A library for providing inter-language foreign function interface calls', - 'long_description': long_description, - 'long_description_content_type': 'text/x-rst', - - # The project's main homepage - 'url': 'https://github.com/metacall/core', - - # Author details - 'author': 'Vicente Eduardo Ferrer Garcia', - 'author_email': 'vic798@gmail.com', - - # License - 'license': 'Apache License 2.0', - - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - 'classifiers': [ - # Project Status - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 4 - Beta', - - # Audience - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Interpreters', - - # Python versions support - #'Programming Language :: Python :: 2', - #'Programming Language :: Python :: 2.6', - #'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', - ], - - # Keywords - 'keywords': 'metacall python port ffi polyglot faas serverless', - - # Modules - 'py_modules': ['metacall'], - - # List additional groups of dependencies here (e.g. development - # dependencies). You can install these using the following syntax, - # for example: - # $ pip install -e .[dev,test] - 'extras_require': { - 'dev': ['check-manifest'], - 'test': ['coverage'], - }, - - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - #package_data: { - # 'sample': ['package_data.dat'], - #}, - - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa - # In this case, 'data_file' will be installed into '<sys.prefix>/my_data' - #data_files: [('my_data', ['data/data_file'])], -} - -# Exclude base packages -exclude_packages = ['contrib', 'docs', 'test', 'test.py' 'CMakeLists.txt', '.gitignore', 'upload.sh'] - -# Define required packages -options['packages'] = find_packages(exclude=exclude_packages) - -# Execute the setup -setup(**options) From 8404af32724d66c700802989611507e105e69b5e Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:51:41 +0200 Subject: [PATCH 039/109] Update port version. --- source/ports/py_port/upload.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index a3aba92f0..e2b992fb3 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -22,7 +22,7 @@ set -exuo pipefail PYPI_VERSION=$(curl -s https://pypi.org/rss/project/metacall/releases.xml | sed -n 's/\s*<title>\([0-9.]*\).*/\1/p' | sed -n '2 p') -PORT_VERSION=$(python3 setup.py --version) +PORT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' pyproject.toml) if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then echo "Current package version is the same as PyPI version, skipping upload." From 20150d60272a457dddf25df3f14914eb05122c3e Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:54:47 +0200 Subject: [PATCH 040/109] Update license version. --- source/ports/py_port/pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 9bf127f9b..aaca782f1 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -9,7 +9,8 @@ description = "A library for providing inter-language foreign function interface keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" requires-python = ">=3.3" -license = { text = "Apache-2.0" } +license = "Apache-2.0" +license-files = ["LICENSE.txt"] authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", From 5d23bb53608a2f8e45d2493dacbc2d91535572dd Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 07:59:20 +0200 Subject: [PATCH 041/109] Remove unused files python package. --- source/ports/py_port/MANIFEST.in | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 source/ports/py_port/MANIFEST.in diff --git a/source/ports/py_port/MANIFEST.in b/source/ports/py_port/MANIFEST.in deleted file mode 100644 index a4fa0c0da..000000000 --- a/source/ports/py_port/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -# Include the license file -include LICENSE.txt - -# Include the data files -recursive-include data * From 51517a8d301230cbc5ada6b3ca1789519b0db74b Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:02:35 +0200 Subject: [PATCH 042/109] Update setuptools. --- source/ports/py_port/pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index aaca782f1..0e69dda30 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61", "wheel"] +requires = ["setuptools>=65", "wheel"] build-backend = "setuptools.build_meta" [project] @@ -39,6 +39,3 @@ Issues = "https://github.com/metacall/core/issues" [tool.setuptools] packages = ["metacall"] - -[tool.setuptools.package-data] -"metacall" = ["*"] From 3ac6927f75374f4c8390c90550cd463c1515f381 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:04:51 +0200 Subject: [PATCH 043/109] Remove license. --- source/ports/py_port/LICENSE.txt | 201 ---------------------------- source/ports/py_port/pyproject.toml | 1 - 2 files changed, 202 deletions(-) delete mode 100644 source/ports/py_port/LICENSE.txt diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt deleted file mode 100644 index d56ad81fa..000000000 --- a/source/ports/py_port/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 0e69dda30..04ac72134 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -10,7 +10,6 @@ keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless readme = "README.rst" requires-python = ">=3.3" license = "Apache-2.0" -license-files = ["LICENSE.txt"] authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", From f36c6b1842b42ad2e7723b24e3191ae8e7aa8041 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> Date: Wed, 2 Jul 2025 02:07:50 -0400 Subject: [PATCH 044/109] Update pyproject.toml --- source/ports/py_port/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 04ac72134..77562f8c0 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -12,6 +12,7 @@ requires-python = ">=3.3" license = "Apache-2.0" authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ + "License :: OSI Approved :: Apache Software License", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Topic :: Software Development :: Interpreters", From d4c26f62f9520b46996c9c9a42f9e701a03d9879 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:11:34 +0200 Subject: [PATCH 045/109] Modify license. --- source/ports/py_port/LICENSE.txt | 201 ++++++++++++++++++++++++++++ source/ports/py_port/pyproject.toml | 3 +- 2 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 source/ports/py_port/LICENSE.txt diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt new file mode 100644 index 000000000..d56ad81fa --- /dev/null +++ b/source/ports/py_port/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 77562f8c0..b55234f78 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -9,10 +9,9 @@ description = "A library for providing inter-language foreign function interface keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" requires-python = ">=3.3" -license = "Apache-2.0" +license = { file = "LICENSE.txt" } authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ - "License :: OSI Approved :: Apache Software License", "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Topic :: Software Development :: Interpreters", From 22750ba0bb7aff2a4126e51408a20f1bff5e0184 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:13:02 +0200 Subject: [PATCH 046/109] License files python package. --- source/ports/py_port/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index b55234f78..55c6bf84b 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -9,7 +9,7 @@ description = "A library for providing inter-language foreign function interface keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" requires-python = ">=3.3" -license = { file = "LICENSE.txt" } +license-files = ["LICENSE.txt"] authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", From 02ddf49476d9b3f36bc2d0c239c3056e2b63d0f4 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:14:14 +0200 Subject: [PATCH 047/109] Remove license completely. --- source/ports/py_port/LICENSE.txt | 201 ---------------------------- source/ports/py_port/pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 202 deletions(-) delete mode 100644 source/ports/py_port/LICENSE.txt diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt deleted file mode 100644 index d56ad81fa..000000000 --- a/source/ports/py_port/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index 55c6bf84b..a1f796411 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -9,7 +9,7 @@ description = "A library for providing inter-language foreign function interface keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" requires-python = ">=3.3" -license-files = ["LICENSE.txt"] +# license-files = ["LICENSE.txt"] authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", From 113ba8c36a95d03546ac4c264dabae44881b72f4 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:16:39 +0200 Subject: [PATCH 048/109] Add license to python package again. --- source/ports/py_port/LICENSE.txt | 201 +++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 source/ports/py_port/LICENSE.txt diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt new file mode 100644 index 000000000..d56ad81fa --- /dev/null +++ b/source/ports/py_port/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 5de40d6e1ba6610dca8e141d8f580b0328c8482d Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:19:09 +0200 Subject: [PATCH 049/109] Add token permissions to python package. --- .github/workflows/release-python.yml | 4 + source/ports/py_port/LICENSE.txt | 201 --------------------------- 2 files changed, 4 insertions(+), 201 deletions(-) delete mode 100644 source/ports/py_port/LICENSE.txt diff --git a/.github/workflows/release-python.yml b/.github/workflows/release-python.yml index d2d96cabd..a5f0c7de4 100644 --- a/.github/workflows/release-python.yml +++ b/.github/workflows/release-python.yml @@ -6,6 +6,10 @@ on: paths: - 'source/ports/py_port/**' +permissions: + id-token: write + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt deleted file mode 100644 index d56ad81fa..000000000 --- a/source/ports/py_port/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. From 9fe130b0f69e3c6b38fc19f1531f1fe500024bdf Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 08:21:48 +0200 Subject: [PATCH 050/109] Remove license from python package completely. --- source/ports/py_port/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml index a1f796411..a693b8d58 100644 --- a/source/ports/py_port/pyproject.toml +++ b/source/ports/py_port/pyproject.toml @@ -9,7 +9,6 @@ description = "A library for providing inter-language foreign function interface keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] readme = "README.rst" requires-python = ">=3.3" -# license-files = ["LICENSE.txt"] authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", From 12668e1d07b34407a30ac470823de4b9ab9dccdd Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 17:02:02 +0200 Subject: [PATCH 051/109] Update version to v0.9.11. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ea8f4fd66..6889a3112 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.10 \ No newline at end of file +0.9.11 \ No newline at end of file From c8339e8a91a80e41c242bab635c952787ceca426 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 17:32:47 +0200 Subject: [PATCH 052/109] Move to setup.py again, it conflicts with distributables. --- source/ports/py_port/LICENSE.txt | 201 ++++++++++++++++++++++++++++ source/ports/py_port/MANIFEST.in | 2 + source/ports/py_port/README.rst | 20 +++ source/ports/py_port/pyproject.toml | 39 ------ source/ports/py_port/setup.py | 134 +++++++++++++++++++ source/ports/py_port/upload.sh | 2 +- 6 files changed, 358 insertions(+), 40 deletions(-) create mode 100644 source/ports/py_port/LICENSE.txt create mode 100644 source/ports/py_port/MANIFEST.in delete mode 100644 source/ports/py_port/pyproject.toml create mode 100644 source/ports/py_port/setup.py diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt new file mode 100644 index 000000000..d56ad81fa --- /dev/null +++ b/source/ports/py_port/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/source/ports/py_port/MANIFEST.in b/source/ports/py_port/MANIFEST.in new file mode 100644 index 000000000..e02cfac5f --- /dev/null +++ b/source/ports/py_port/MANIFEST.in @@ -0,0 +1,2 @@ +# Include the license file +include LICENSE.txt diff --git a/source/ports/py_port/README.rst b/source/ports/py_port/README.rst index 27c27ab53..6947e5c09 100644 --- a/source/ports/py_port/README.rst +++ b/source/ports/py_port/README.rst @@ -51,6 +51,26 @@ Calling Ruby from Python metacall('multiply', 3, 4); # 12 +Calling NodeJS from Python (MonkeyPatch API) +------------------------ + +``sum.js`` + +.. code:: js + + module.exports = { + sum: (x, y) => x + y, + }; + +``main.py`` + +.. code:: python + + import metacall + from sum.js import sum + + sum(3, 4); # 7 + Running the example: .. code:: console diff --git a/source/ports/py_port/pyproject.toml b/source/ports/py_port/pyproject.toml deleted file mode 100644 index a693b8d58..000000000 --- a/source/ports/py_port/pyproject.toml +++ /dev/null @@ -1,39 +0,0 @@ -[build-system] -requires = ["setuptools>=65", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "metacall" -version = "0.5.2" -description = "A library for providing inter-language foreign function interface calls" -keywords = ["metacall", "python", "port", "ffi", "polyglot", "faas", "serverless"] -readme = "README.rst" -requires-python = ">=3.3" -authors = [{ name = "Vicente Eduardo Ferrer Garcia", email = "vic798@gmail.com" }] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Topic :: Software Development :: Interpreters", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13" -] -dependencies = [] - -[project.urls] -Homepage = "https://metacall.io/" -Repository = "https://github.com/metacall/core" -Documentation = "https://core.metacall.io/" -Issues = "https://github.com/metacall/core/issues" - -[tool.setuptools] -packages = ["metacall"] diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py new file mode 100644 index 000000000..f5094e04c --- /dev/null +++ b/source/ports/py_port/setup.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +# MetaCall Python Port by Parra Studios +# A frontend for Python language bindings in MetaCall. +# +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# To use a consistent encoding +from codecs import open +import os +import sys +import re + +# Always prefer setuptools over distutils +from setuptools import setup, find_packages + +current_path = os.path.abspath(os.path.dirname(__file__)) + +# Get the long description from the README file +with open(os.path.join(current_path, 'README.rst'), encoding='utf-8') as f: + long_description = f.read() + +# Define set up options +options = { + 'name': 'metacall', + + # Versions should comply with PEP440. For a discussion on single-sourcing + # the version across setup.py and the project code, see + # https://packaging.python.org/en/latest/single_source_version.html + 'version': '0.5.3', + + 'description': 'A library for providing inter-language foreign function interface calls', + 'long_description': long_description, + 'long_description_content_type': 'text/x-rst', + + # The project's main homepage + 'url': 'https://github.com/metacall/core', + + 'project_urls': { + 'Homepage': 'https://metacall.io/', + 'Repository': 'https://github.com/metacall/core', + 'Documentation': 'https://core.metacall.io/', + 'Issues': 'https://github.com/metacall/core/issues', + }, + + # Author details + 'author': 'Vicente Eduardo Ferrer Garcia', + 'author_email': 'vic798@gmail.com', + + # License + 'license': 'Apache License 2.0', + + # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + 'classifiers': [ + # Project Status + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + 'Development Status :: 4 - Beta', + + # Audience + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Interpreters', + + # Python versions support + #'Programming Language :: Python :: 2', + #'Programming Language :: Python :: 2.6', + #'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', + ], + + # Keywords + 'keywords': 'metacall python port ffi polyglot faas serverless', + + # Required Python version + 'python_requires': '>=3.3', + + # Dependencies + 'install_requires': [], + + # List additional groups of dependencies here (e.g. development + # dependencies). You can install these using the following syntax, + # for example: + # $ pip install -e .[dev,test] + 'extras_require': { + 'dev': ['check-manifest'], + 'test': ['coverage'], + }, + + # If there are data files included in your packages that need to be + # installed, specify them here. If using Python 2.6 or less, then these + # have to be included in MANIFEST.in as well. + #package_data: { + # 'sample': ['package_data.dat'], + #}, + + # Although 'package_data' is the preferred approach, in some case you may + # need to place data files outside of your packages. See: + # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa + # In this case, 'data_file' will be installed into '<sys.prefix>/my_data' + #data_files: [('my_data', ['data/data_file'])], +} + +# Exclude base packages +exclude_packages = ['contrib', 'docs', 'test', 'test.py', 'CMakeLists.txt', '.gitignore', 'upload.sh'] + +# Define required packages +options['packages'] = find_packages(exclude=exclude_packages) + +# Execute the setup +setup(**options) diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index e2b992fb3..a3aba92f0 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -22,7 +22,7 @@ set -exuo pipefail PYPI_VERSION=$(curl -s https://pypi.org/rss/project/metacall/releases.xml | sed -n 's/\s*<title>\([0-9.]*\).*/\1/p' | sed -n '2 p') -PORT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' pyproject.toml) +PORT_VERSION=$(python3 setup.py --version) if [[ "$PYPI_VERSION" == "$PORT_VERSION" ]]; then echo "Current package version is the same as PyPI version, skipping upload." From 913ae9dc5c4411953d95c5c26fe7e933491c1968 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 17:34:22 +0200 Subject: [PATCH 053/109] Remove license from python package,. --- source/ports/py_port/LICENSE.txt | 201 ------------------------------- source/ports/py_port/MANIFEST.in | 2 - 2 files changed, 203 deletions(-) delete mode 100644 source/ports/py_port/LICENSE.txt delete mode 100644 source/ports/py_port/MANIFEST.in diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt deleted file mode 100644 index d56ad81fa..000000000 --- a/source/ports/py_port/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/source/ports/py_port/MANIFEST.in b/source/ports/py_port/MANIFEST.in deleted file mode 100644 index e02cfac5f..000000000 --- a/source/ports/py_port/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -# Include the license file -include LICENSE.txt From 69f2aa51087b490059ef65624103dae72c006f5f Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 17:35:47 +0200 Subject: [PATCH 054/109] Solve issues. --- source/ports/py_port/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/py_port/README.rst b/source/ports/py_port/README.rst index 6947e5c09..469dad730 100644 --- a/source/ports/py_port/README.rst +++ b/source/ports/py_port/README.rst @@ -52,7 +52,7 @@ Calling Ruby from Python metacall('multiply', 3, 4); # 12 Calling NodeJS from Python (MonkeyPatch API) ------------------------- +-------------------------------------------- ``sum.js`` From b5c5fa940ddcfe51a59f9c6c5dbbb35f8fa17c32 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 2 Jul 2025 18:01:19 +0200 Subject: [PATCH 055/109] Update to version v0.9.12. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6889a3112..bf1ba0c17 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.11 \ No newline at end of file +0.9.12 \ No newline at end of file From 54b6b15e6288fabf61a143e631c439854546955a Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:18:14 -0400 Subject: [PATCH 056/109] Update docker-hub.yml --- .github/workflows/docker-hub.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 907dc9ba3..34267338a 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -81,6 +81,8 @@ jobs: version: v${{ env.BUILDKIT_VERSION }} - name: Login to Docker Hub + # Only run when master or when tagging a version + if: (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) && github.event_name != 'pull_request' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} From ae05b71b9a088720f331a99596372f40327cd7f0 Mon Sep 17 00:00:00 2001 From: Mahdi Sharifi <devraymondsh@gmail.com> Date: Wed, 9 Jul 2025 02:49:46 +0330 Subject: [PATCH 057/109] Implement metacall_box for passing function arguments with different types (#538) * Implement metacall_box for passing function arguments with different types * Update metacall_test.rs --------- Co-authored-by: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> --- source/ports/rs_port/src/cast.rs | 2 +- source/ports/rs_port/src/lib.rs | 1 + .../rs_port/src/types/metacall_exception.rs | 2 +- .../ports/rs_port/src/types/metacall_value.rs | 33 +++++++++++++++++ source/ports/rs_port/tests/metacall_test.rs | 36 ++++++++----------- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/source/ports/rs_port/src/cast.rs b/source/ports/rs_port/src/cast.rs index 51574fdf1..61e4c3e8c 100644 --- a/source/ports/rs_port/src/cast.rs +++ b/source/ports/rs_port/src/cast.rs @@ -235,6 +235,6 @@ pub fn metacallobj_untyped_to_raw(ret: Box<dyn MetaCallValue>) -> Option<*mut c_ None } -pub fn metacall_implementer_to_traitobj(v: impl MetaCallValue) -> Box<dyn MetaCallValue> { +pub fn metacall_box(v: impl MetaCallValue) -> Box<dyn MetaCallValue> { Box::new(v) as Box<dyn MetaCallValue> } diff --git a/source/ports/rs_port/src/lib.rs b/source/ports/rs_port/src/lib.rs index ac93df572..328236d57 100644 --- a/source/ports/rs_port/src/lib.rs +++ b/source/ports/rs_port/src/lib.rs @@ -88,6 +88,7 @@ pub use types::*; #[doc(hidden)] mod init; +pub use cast::metacall_box; pub use init::initialize; pub use init::is_initialized; diff --git a/source/ports/rs_port/src/types/metacall_exception.rs b/source/ports/rs_port/src/types/metacall_exception.rs index c3bf662cc..f753fce6c 100644 --- a/source/ports/rs_port/src/types/metacall_exception.rs +++ b/source/ports/rs_port/src/types/metacall_exception.rs @@ -180,7 +180,7 @@ impl MetaCallThrowable { Ok(mut value) => { value.leak = true; - cast::metacall_implementer_to_traitobj(value) + cast::metacall_box(value) } Err(original) => original, } diff --git a/source/ports/rs_port/src/types/metacall_value.rs b/source/ports/rs_port/src/types/metacall_value.rs index 97a669567..bbc5870ff 100644 --- a/source/ports/rs_port/src/types/metacall_value.rs +++ b/source/ports/rs_port/src/types/metacall_value.rs @@ -429,3 +429,36 @@ impl MetaCallValue for MetaCallThrowable { self.into_raw() } } +/// Just a Rust barrier made for easier polymorphism. +impl MetaCallValue for Box<dyn MetaCallValue> { + fn get_metacall_id() -> metacall_value_id { + metacall_value_id::METACALL_INVALID + } + fn from_metacall_raw_leak(v: *mut c_void) -> Result<Self, Box<dyn MetaCallValue>> { + Ok(cast::raw_to_metacallobj_untyped_leak(v)) + } + fn into_metacall_raw(self) -> *mut c_void { + match_metacall_value!(self, { + bool: bool => bool.into_metacall_raw(), + char: char => char.into_metacall_raw(), + num: i16 => num.into_metacall_raw(), + num: i32 => num.into_metacall_raw(), + num: i64 => num.into_metacall_raw(), + num: f32 => num.into_metacall_raw(), + num: f64 => num.into_metacall_raw(), + str: String => str.into_metacall_raw(), + buf: Vec<i8> => buf.into_metacall_raw(), + arr: Vec<Box<dyn MetaCallValue>> => arr.into_metacall_raw(), + map: HashMap<String, Box<dyn MetaCallValue>> => map.into_metacall_raw(), + ptr: MetaCallPointer => ptr.into_metacall_raw(), + fut: MetaCallFuture => fut.into_metacall_raw(), + fun: MetaCallFunction => fun.into_metacall_raw(), + null: MetaCallNull => null.into_metacall_raw(), + cls: MetaCallClass => cls.into_metacall_raw(), + obj: MetaCallObject => obj.into_metacall_raw(), + exc: MetaCallException => exc.into_metacall_raw(), + thr: MetaCallThrowable => thr.into_metacall_raw(), + _ => MetaCallNull().into_metacall_raw() + }) + } +} diff --git a/source/ports/rs_port/tests/metacall_test.rs b/source/ports/rs_port/tests/metacall_test.rs index ad6389262..d23e2e2ae 100644 --- a/source/ports/rs_port/tests/metacall_test.rs +++ b/source/ports/rs_port/tests/metacall_test.rs @@ -81,27 +81,22 @@ fn test_float() { fn test_double() { generate_test::<f64>("test_double", 1.2345_f64); } -// TODO -// fn test_mixed_numbers() { -// let result = ::metacall::metacall::<i64>( -// "test_mixed_numbers", -// [ -// Box::new(1 as i16) as Box<dyn MetaCallValue>, -// Box::new(2 as i32) as Box<dyn MetaCallValue>, -// Box::new(3 as i64) as Box<dyn MetaCallValue>, -// ], -// ); - -// // TODO -// // ::metacall::metacall::<i64>("test_mixed_numbers", [1_i16, 2_i32, 3_i64]); -// // ::metacall::metacall::<i64>("test_mixed_numbers", (1_i16, 2_i32, 3_i64)); +fn test_mixed_numbers() { + let result = ::metacall::metacall::<i64>( + "test_mixed_numbers", + [ + ::metacall::metacall_box(1 as i16), + ::metacall::metacall_box(2 as i32), + ::metacall::metacall_box(3 as i64), + ], + ); -// assert!(result.is_ok()); + assert!(result.is_ok()); -// if let Ok(ret) = result { -// assert_eq!(ret, 6_i64) -// } -// } + if let Ok(ret) = result { + assert_eq!(ret, 6_i64) + } +} fn test_string() { generate_test::<String>( "return_the_argument_py", @@ -393,8 +388,7 @@ fn metacall() { test_int(); test_long(); test_short(); - // TODO - // test_mixed_numbers(); + test_mixed_numbers(); } if load::from_single_file("node", js_test_file).is_ok() { test_exception(); From 81faf03ff665a2014a247a1c7c4fb08f25164e6b Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 9 Jul 2025 17:04:08 +0200 Subject: [PATCH 058/109] Remove PORT_LIBRARY_PATH. --- docker-compose.yml | 3 --- source/CMakeLists.txt | 8 -------- source/ports/rs_port/CMakeLists.txt | 1 - tools/cli/Dockerfile | 1 - tools/dev/Dockerfile | 1 - tools/metacall-sanitizer.sh | 1 - tools/runtime/Dockerfile | 1 - 7 files changed, 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f74866582..1c1997b13 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -64,7 +64,6 @@ services: CONFIGURATION_PATH: $METACALL_PATH/build/configurations/global.json SERIAL_LIBRARY_PATH: $METACALL_PATH/build DETOUR_LIBRARY_PATH: $METACALL_PATH/build - PORT_LIBRARY_PATH: $METACALL_PATH/build NODE_PATH: /usr/lib/node_modules runtime: @@ -88,7 +87,6 @@ services: CONFIGURATION_PATH: /usr/local/share/metacall/configurations/global.json SERIAL_LIBRARY_PATH: /usr/local/lib DETOUR_LIBRARY_PATH: /usr/local/lib - PORT_LIBRARY_PATH: /usr/local/lib NODE_PATH: /usr/local/lib/node_modules cli: @@ -108,5 +106,4 @@ services: CONFIGURATION_PATH: /usr/local/share/metacall/configurations/global.json SERIAL_LIBRARY_PATH: /usr/local/lib DETOUR_LIBRARY_PATH: /usr/local/lib - PORT_LIBRARY_PATH: /usr/local/lib NODE_PATH: /usr/local/lib/node_modules diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 883be65c3..b7c1e402b 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -18,9 +18,6 @@ set(SERIAL_LIBRARY_PATH "@OUTPUT_DIRECTORY_DIR@" CACHE PATH "MetaCall serial lib # Export output detour plugin directory set(DETOUR_LIBRARY_PATH "@OUTPUT_DIRECTORY_DIR@" CACHE PATH "MetaCall detour library path") -# Export output port directory -set(PORT_LIBRARY_PATH "@OUTPUT_DIRECTORY_DIR@" CACHE PATH "MetaCall port library path") - # Add extra environment varible set(EXTRA_ENVIRONMENT_VARIABLES "" CACHE PATH "MetaCall extra environment variable") @@ -54,16 +51,11 @@ set(TESTS_DETOUR_ENVIRONMENT_VARIABLES "DETOUR_LIBRARY_PATH=${DETOUR_LIBRARY_PATH}" ) -set(TESTS_PORT_ENVIRONMENT_VARIABLES - "PORT_LIBRARY_PATH=${PORT_LIBRARY_PATH}" -) - set(TESTS_ENVIRONMENT_VARIABLES ${TESTS_LOADER_ENVIRONMENT_VARIABLES} ${TESTS_CONFIGURATION_ENVIRONMENT_VARIABLES} ${TESTS_SERIAL_ENVIRONMENT_VARIABLES} ${TESTS_DETOUR_ENVIRONMENT_VARIABLES} - ${TESTS_PORT_ENVIRONMENT_VARIABLES} ${TESTS_SANITIZER_ENVIRONMENT_VARIABLES} ${TESTS_MEMCHECK_ENVIRONMENT_VARIABLES} ${EXTRA_ENVIRONMENT_VARIABLES} diff --git a/source/ports/rs_port/CMakeLists.txt b/source/ports/rs_port/CMakeLists.txt index 548d583b9..972c34922 100644 --- a/source/ports/rs_port/CMakeLists.txt +++ b/source/ports/rs_port/CMakeLists.txt @@ -215,7 +215,6 @@ set(RS_PORT_DEBUG_ENVIRONMENT_VARIABLES "CONFIGURATION_PATH=${PROJECT_OUTPUT_DIR}/configurations/global.json" "SERIAL_LIBRARY_PATH=${PROJECT_OUTPUT_DIR}" "DETOUR_LIBRARY_PATH=${PROJECT_OUTPUT_DIR}" - "PORT_LIBRARY_PATH=${PROJECT_OUTPUT_DIR}" "${PROJECT_LIBRARY_PATH_NAME}=${TEST_LIB_PATH}" ) diff --git a/tools/cli/Dockerfile b/tools/cli/Dockerfile index fed409c5e..0da28539b 100644 --- a/tools/cli/Dockerfile +++ b/tools/cli/Dockerfile @@ -37,7 +37,6 @@ ENV LOADER_LIBRARY_PATH=/usr/local/lib \ CONFIGURATION_PATH=/usr/local/share/metacall/configurations/global.json \ SERIAL_LIBRARY_PATH=/usr/local/lib \ DETOUR_LIBRARY_PATH=/usr/local/lib \ - PORT_LIBRARY_PATH=/usr/local/lib \ DEBIAN_FRONTEND=noninteractive \ NODE_PATH=/usr/local/lib/node_modules \ DOTNET_CLI_TELEMETRY_OPTOUT=true diff --git a/tools/dev/Dockerfile b/tools/dev/Dockerfile index 9f5805944..ec35dfde4 100644 --- a/tools/dev/Dockerfile +++ b/tools/dev/Dockerfile @@ -37,7 +37,6 @@ ENV LOADER_LIBRARY_PATH=$METACALL_PATH/build \ CONFIGURATION_PATH=$METACALL_PATH/build/configurations/global.json \ SERIAL_LIBRARY_PATH=$METACALL_PATH/build \ DETOUR_LIBRARY_PATH=$METACALL_PATH/build \ - PORT_LIBRARY_PATH=$METACALL_PATH/build \ DEBIAN_FRONTEND=noninteractive \ NODE_PATH=/usr/lib/node_modules \ DOTNET_CLI_TELEMETRY_OPTOUT=true diff --git a/tools/metacall-sanitizer.sh b/tools/metacall-sanitizer.sh index 6605ac112..cd3f08b40 100755 --- a/tools/metacall-sanitizer.sh +++ b/tools/metacall-sanitizer.sh @@ -44,7 +44,6 @@ export LOADER_SCRIPT_PATH="${BUILD_DIR}/scripts" export CONFIGURATION_PATH="${BUILD_DIR}/configurations/global.json" export SERIAL_LIBRARY_PATH="${BUILD_DIR}" export DETOUR_LIBRARY_PATH="${BUILD_DIR}" -export PORT_LIBRARY_PATH="${BUILD_DIR}" BUILD_OPTIONS=( ${BUILD_SANITIZER} debug ${BUILD_LANGUAGES[@]} examples tests scripts ports install pack benchmarks diff --git a/tools/runtime/Dockerfile b/tools/runtime/Dockerfile index 1276b7e11..4ac47f518 100644 --- a/tools/runtime/Dockerfile +++ b/tools/runtime/Dockerfile @@ -61,7 +61,6 @@ ENV LOADER_LIBRARY_PATH=/usr/local/lib \ CONFIGURATION_PATH=/usr/local/share/metacall/configurations/global.json \ SERIAL_LIBRARY_PATH=/usr/local/lib \ DETOUR_LIBRARY_PATH=/usr/local/lib \ - PORT_LIBRARY_PATH=/usr/local/lib \ DEBIAN_FRONTEND=noninteractive \ NODE_PATH=/usr/local/lib/node_modules \ DOTNET_CLI_TELEMETRY_OPTOUT=true From a0f4a115b31ed95e3612ccb187118f7ed53368b1 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 9 Jul 2025 17:04:52 +0200 Subject: [PATCH 059/109] Update version of node port in lockfile. --- source/ports/node_port/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/node_port/package-lock.json b/source/ports/node_port/package-lock.json index 33e7e61c0..8fc04f897 100644 --- a/source/ports/node_port/package-lock.json +++ b/source/ports/node_port/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "metacall", - "version": "0.5.0", + "version": "0.5.1", "license": "Apache-2.0", "devDependencies": { "mocha": "^9.2.1" From d6103ee5cfb7bed1454fe99f1871d9598ee309e1 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 9 Jul 2025 17:05:19 +0200 Subject: [PATCH 060/109] Add support to relative paths in configurations. --- .../configuration/configuration_object.h | 21 ++ .../configuration/source/configuration_impl.c | 63 ++--- .../source/configuration_object.c | 37 ++- source/loader/source/loader_impl.c | 14 +- source/tests/CMakeLists.txt | 1 + .../CMakeLists.txt | 265 ++++++++++++++++++ .../data/configurations/global.json.in | 3 + .../data/configurations/py_loader.json.in | 8 + .../data/scripts/main.py | 6 + ...l_configuration_exec_relative_path_test.py | 4 + .../source/main.cpp | 28 ++ ..._configuration_exec_relative_path_test.cpp | 59 ++++ 12 files changed, 457 insertions(+), 52 deletions(-) create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/CMakeLists.txt create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/data/configurations/global.json.in create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/data/configurations/py_loader.json.in create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/data/scripts/main.py create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/data/scripts/metacall_configuration_exec_relative_path_test.py create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/source/main.cpp create mode 100644 source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp diff --git a/source/configuration/include/configuration/configuration_object.h b/source/configuration/include/configuration/configuration_object.h index 2c22e6eb2..7a5f88679 100644 --- a/source/configuration/include/configuration/configuration_object.h +++ b/source/configuration/include/configuration/configuration_object.h @@ -76,6 +76,27 @@ CONFIGURATION_API configuration configuration_object_initialize(const char *name */ CONFIGURATION_API int configuration_object_childs(configuration config, vector childs, set storage); +/** +* @brief +* Get an absolute path from the value @v which is a string representing a path, +* if the path is absolute, store it in @path as it is, otherwise, join the @config +* path to the value string @v and make it canonical +* +* @param[in] config +* Pointer to configuration object +* +* @param[in] v +* The value representing the path +* +* @param[out] path +* The string where it is going to be store the path +* +* @return +* Returns the size of the path +* +*/ +CONFIGURATION_API size_t configuration_object_child_path(configuration config, value v, char *path); + /** * @brief * Set value of configuration object @config diff --git a/source/configuration/source/configuration_impl.c b/source/configuration/source/configuration_impl.c index ca61ed14b..5482f7375 100644 --- a/source/configuration/source/configuration_impl.c +++ b/source/configuration/source/configuration_impl.c @@ -69,18 +69,15 @@ int configuration_impl_initialize(const char *name) int configuration_impl_load(configuration config, void *allocator) { configuration_impl_singleton singleton = configuration_impl_singleton_instance(); - - set storage; - vector queue, childs; - - storage = set_create(&hash_callback_str, &comparable_callback_str); + set storage = set_create(&hash_callback_str, &comparable_callback_str); + int result = 1; if (storage == NULL) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation load set allocation"); - return 1; + goto alloc_storage_error; } queue = vector_create(sizeof(configuration)); @@ -89,9 +86,7 @@ int configuration_impl_load(configuration config, void *allocator) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation load queue allocation"); - set_destroy(storage); - - return 1; + goto alloc_queue_error; } childs = vector_create(sizeof(configuration)); @@ -100,11 +95,7 @@ int configuration_impl_load(configuration config, void *allocator) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation load childs allocation"); - set_destroy(storage); - - vector_destroy(queue); - - return 1; + goto alloc_childs_error; } vector_push_back(queue, &config); @@ -131,13 +122,7 @@ int configuration_impl_load(configuration config, void *allocator) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation load (childs) <%p>", current); - set_destroy(storage); - - vector_destroy(queue); - - vector_destroy(childs); - - return 1; + goto load_error; } } @@ -145,7 +130,12 @@ int configuration_impl_load(configuration config, void *allocator) vector_clear(childs); - if (configuration_object_childs(current, childs, storage) == 0 && vector_size(childs) > 0) + if (configuration_object_childs(current, childs, storage) != 0) + { + goto load_error; + } + + if (vector_size(childs) > 0) { size_t iterator; @@ -160,13 +150,7 @@ int configuration_impl_load(configuration config, void *allocator) log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation child singleton insertion (%s, %s)", configuration_object_name(child), configuration_object_path(child)); - set_destroy(storage); - - vector_destroy(queue); - - vector_destroy(childs); - - return 1; + goto load_error; } vector_push_back(queue, &child); @@ -176,25 +160,22 @@ int configuration_impl_load(configuration config, void *allocator) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid configuration implementation child set insertion"); - set_destroy(storage); - - vector_destroy(queue); - - vector_destroy(childs); - - return 1; + goto load_error; } } } } - set_destroy(storage); - - vector_destroy(queue); + result = 0; +load_error: vector_destroy(childs); - - return 0; +alloc_childs_error: + vector_destroy(queue); +alloc_queue_error: + set_destroy(storage); +alloc_storage_error: + return result; } int configuration_impl_destroy(void) diff --git a/source/configuration/source/configuration_object.c b/source/configuration/source/configuration_object.c index 57c7ab9cd..e49e8a733 100644 --- a/source/configuration/source/configuration_object.c +++ b/source/configuration/source/configuration_object.c @@ -13,6 +13,8 @@ #include <log/log.h> +#include <portability/portability_path.h> + #include <string.h> /* -- Member Data -- */ @@ -102,6 +104,8 @@ configuration configuration_object_initialize(const char *name, const char *path if (config->source == NULL) { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load configuration %s from %s", name, path); + free(config); return NULL; @@ -216,6 +220,31 @@ int configuration_object_childs_valid(set_key key, set_value val) return 1; } +size_t configuration_object_child_path(configuration config, value v, char *path) +{ + const char *value_path = value_to_string(v); + size_t size = value_type_size(v); + + if (portability_path_is_absolute(value_path, size) == 0) + { + memcpy(path, value_path, size); + } + else + { + char absolute_path[PORTABILITY_PATH_SIZE]; + + size_t absolute_path_size = portability_path_get_directory(config->path, strnlen(config->path, PORTABILITY_PATH_SIZE), absolute_path, PORTABILITY_PATH_SIZE); + + char join_path[PORTABILITY_PATH_SIZE]; + + size_t join_path_size = portability_path_join(absolute_path, absolute_path_size, value_path, size, join_path, PORTABILITY_PATH_SIZE); + + size = portability_path_canonical(join_path, join_path_size, path, PORTABILITY_PATH_SIZE); + } + + return size; +} + int configuration_object_childs(configuration config, vector childs, set storage) { struct set_iterator_type it; @@ -229,11 +258,13 @@ int configuration_object_childs(configuration config, vector childs, set storage { if (set_get(storage, key) == NULL) { - value v = val; + char path[PORTABILITY_PATH_SIZE]; + + configuration child; - const char *path = value_to_string(v); + configuration_object_child_path(config, val, path); - configuration child = configuration_object_initialize(key, path, config); + child = configuration_object_initialize(key, path, config); if (child == NULL) { diff --git a/source/loader/source/loader_impl.c b/source/loader/source/loader_impl.c index c66b2bfd4..260a787af 100644 --- a/source/loader/source/loader_impl.c +++ b/source/loader/source/loader_impl.c @@ -35,6 +35,7 @@ #include <log/log.h> #include <configuration/configuration.h> +#include <configuration/configuration_object.h> #include <portability/portability_library_path.h> @@ -282,16 +283,13 @@ void loader_impl_configuration_execution_paths(loader_impl_interface iface, load { if (value_type_id(execution_paths_array[iterator]) == TYPE_STRING) { - const char *str = value_to_string(execution_paths_array[iterator]); - size_t str_size = value_type_size(execution_paths_array[iterator]); + loader_path execution_path; - if (str != NULL) - { - loader_path execution_path; - - strncpy(execution_path, str, str_size > LOADER_PATH_SIZE ? LOADER_PATH_SIZE : str_size); + configuration_object_child_path(impl->config, execution_paths_array[iterator], execution_path); - iface->execution_path(impl, execution_path); + if (iface->execution_path(impl, execution_path) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load execution path %s in configuration %s", execution_path, configuration_object_name(impl->config)); } } } diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index bf31bbbf9..6e6ad2ffc 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -158,6 +158,7 @@ add_subdirectory(metacall_inspect_test) add_subdirectory(metacall_integration_test) add_subdirectory(metacall_depends_test) add_subdirectory(metacall_configuration_exec_path_test) +add_subdirectory(metacall_configuration_exec_relative_path_test) add_subdirectory(metacall_configuration_default_test) add_subdirectory(metacall_clear_test) add_subdirectory(metacall_python_test) diff --git a/source/tests/metacall_configuration_exec_relative_path_test/CMakeLists.txt b/source/tests/metacall_configuration_exec_relative_path_test/CMakeLists.txt new file mode 100644 index 000000000..93ad2822f --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/CMakeLists.txt @@ -0,0 +1,265 @@ +# Check if python loader is enabled +if(NOT OPTION_BUILD_LOADERS_PY) + return() +endif() + +# +# Executable name and options +# + +# Target name +set(target metacall-configuration-exec-relative-path-test) +message(STATUS "Test ${target}") + +# +# Compiler warnings +# + +include(Warnings) + +# +# Compiler security +# + +include(SecurityFlags) + +# +# Sources +# + +set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") +set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") + +set(sources + ${source_path}/main.cpp + ${source_path}/metacall_configuration_exec_relative_path_test.cpp +) + +# Group source files +set(header_group "Header Files (API)") +set(source_group "Source Files") +source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" + ${header_group} ${headers}) +source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" + ${source_group} ${sources}) + +# +# Create executable +# + +# Build executable +add_executable(${target} + ${sources} +) + +# Create namespaced alias +add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) + +# +# Dependecies +# + +add_dependencies(${target} + ${META_PROJECT_NAME}::metacall +) + +# +# Project options +# + +set_target_properties(${target} + PROPERTIES + ${DEFAULT_PROJECT_OPTIONS} + FOLDER "${IDE_FOLDER}" +) + +# +# Include directories +# + +target_include_directories(${target} + PRIVATE + ${DEFAULT_INCLUDE_DIRECTORIES} + ${PROJECT_BINARY_DIR}/source/include +) + +# +# Libraries +# + +target_link_libraries(${target} + PRIVATE + ${DEFAULT_LIBRARIES} + + GTest + + ${META_PROJECT_NAME}::metacall +) + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + ${DEFAULT_COMPILE_DEFINITIONS} +) + +# +# Compile options +# + +target_compile_options(${target} + PRIVATE + ${DEFAULT_COMPILE_OPTIONS} +) + +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + +# +# Linker options +# + +target_link_options(${target} + PRIVATE + ${DEFAULT_LINKER_OPTIONS} +) + +# +# Define test +# + +add_test(NAME ${target} + COMMAND $<TARGET_FILE:${target}> +) + +# +# Define dependencies +# + +add_dependencies(${target} + py_loader +) + +# +# Set test variables +# + +set(PY_LOADER_SCRIPT_PATH "${CMAKE_CURRENT_BINARY_DIR}/scripts") +set(PY_CONFIGURATION_PATH "${CMAKE_CURRENT_BINARY_DIR}/configurations") +set(PY_EXECUTION_PATH "${PY_LOADER_SCRIPT_PATH}/a/b/c/d/e") + +# +# Define test properties +# + +set_property(TEST ${target} + PROPERTY LABELS ${target} +) + +if(OPTION_BUILD_ADDRESS_SANITIZER) + # TODO: This test fails when run with sanitizers: + # ERROR: LeakSanitizer: detected memory leaks + # + # Direct leak of 551991 byte(s) in 221 object(s) allocated from: + # #0 0x7f3819e399cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 + # #1 0x7f38161499c7 (/usr/lib/x86_64-linux-gnu/libpython3.9.so.1.0+0x1169c7) + # + # Direct leak of 1344 byte(s) in 2 object(s) allocated from: + # #0 0x7f3819e388d5 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85 + # #1 0x7f38162370d4 in _PyObject_GC_Resize (/usr/lib/x86_64-linux-gnu/libpython3.9.so.1.0+0x2040d4) + # + # Direct leak of 64 byte(s) in 2 object(s) allocated from: + # #0 0x7f3819e399cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 + # #1 0x7f381622e105 in PyThread_allocate_lock (/usr/lib/x86_64-linux-gnu/libpython3.9.so.1.0+0x1fb105) + # + # Indirect leak of 238277 byte(s) in 249 object(s) allocated from: + # #0 0x7f3819e399cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 + # #1 0x7f38161499c7 (/usr/lib/x86_64-linux-gnu/libpython3.9.so.1.0+0x1169c7) + # + # SUMMARY: AddressSanitizer: 791676 byte(s) leaked in 474 allocation(s). + # + # For solving this, we should enable Python support for sanitizers and debug it properly + set_tests_properties(${target} PROPERTIES + PASS_REGULAR_EXPRESSION "[ PASSED ]" + ) +endif() + +include(TestEnvironmentVariables) + +test_environment_variables(${target} + "" + "LOADER_LIBRARY_PATH=${LOADER_LIBRARY_PATH}" + "LOADER_SCRIPT_PATH=${PY_LOADER_SCRIPT_PATH}" + "CONFIGURATION_PATH=${PY_CONFIGURATION_PATH}/global.json" + "SERIAL_LIBRARY_PATH=${SERIAL_LIBRARY_PATH}" + "DETOUR_LIBRARY_PATH=${DETOUR_LIBRARY_PATH}" + "${TESTS_SANITIZER_ENVIRONMENT_VARIABLES}" +) + +# +# External dependencies +# + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(Python3_FIND_ABI "ON" "ANY" "ANY") + find_package(Python3 COMPONENTS Development) + + # Fallback to release if not found + if(NOT Python3_Development_FOUND) + set(Python3_FIND_ABI) + find_package(Python3 COMPONENTS Development REQUIRED) + endif() +else() + find_package(Python3 COMPONENTS Development REQUIRED) +endif() + +# Find Python DLL +include(Portability) + +if(PROJECT_OS_FAMILY STREQUAL win32 AND Python3_LIBRARIES AND Python3_ROOT_DIR AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + foreach(library ${Python3_LIBRARIES}) + if(${library} MATCHES "[^_d][.]lib$") + # Get the library path with dll suffix + string(REGEX REPLACE "[.]lib$" ".dll" LIB_PATH ${library}) + # Get the library name + get_filename_component(LIB_NAME "${LIB_PATH}" NAME) + # Find the library in the Python3 root path + find_file(Python3_LIBRARY_NAME_PATH ${LIB_NAME} + PATHS ${Python3_ROOT_DIR} + NO_DEFAULT_PATH + ) + if(Python3_LIBRARY_NAME_PATH) + break() + endif() + endif() + endforeach() +endif() + +if(NOT Python3_LIBRARY_NAME_PATH) + set(Python3_LIBRARY_NAME_PATH "${Python3_LIBRARIES}") +endif() + +# +# Configure test data +# + +file(COPY data/scripts/main.py DESTINATION ${PY_LOADER_SCRIPT_PATH}) + +file(COPY data/scripts/metacall_configuration_exec_relative_path_test.py DESTINATION ${PY_EXECUTION_PATH}) + +# Set relative paths +set(PY_CONFIGURATION_OUTPUT_PATH "${PY_CONFIGURATION_PATH}") +set(PY_CONFIGURATION_PATH ".") +set(PY_EXECUTION_PATH "../scripts/a/b/c/d/e") + +configure_file(data/configurations/global.json.in ${PY_CONFIGURATION_OUTPUT_PATH}/global.json @ONLY) + +configure_file(data/configurations/py_loader.json.in ${PY_CONFIGURATION_OUTPUT_PATH}/py_loader.json @ONLY) diff --git a/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/global.json.in b/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/global.json.in new file mode 100644 index 000000000..ca417e6a7 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/global.json.in @@ -0,0 +1,3 @@ +{ + "py_loader":"@PY_CONFIGURATION_PATH@/py_loader.json" +} diff --git a/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/py_loader.json.in b/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/py_loader.json.in new file mode 100644 index 000000000..02a8e81f9 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/data/configurations/py_loader.json.in @@ -0,0 +1,8 @@ +{ + "execution_paths": [ + "@PY_EXECUTION_PATH@" + ], + "dependencies": { + "python": ["@Python3_LIBRARY_NAME_PATH@"] + } +} diff --git a/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/main.py b/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/main.py new file mode 100644 index 000000000..a34daba89 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/main.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import metacall_configuration_exec_relative_path_test + +def main(): + return metacall_configuration_exec_relative_path_test.hello_world('test') diff --git a/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/metacall_configuration_exec_relative_path_test.py b/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/metacall_configuration_exec_relative_path_test.py new file mode 100644 index 000000000..5a8d8d156 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/data/scripts/metacall_configuration_exec_relative_path_test.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 + +def hello_world(text): + return 'Python hello_world: ' + text diff --git a/source/tests/metacall_configuration_exec_relative_path_test/source/main.cpp b/source/tests/metacall_configuration_exec_relative_path_test/source/main.cpp new file mode 100644 index 000000000..582034129 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/source/main.cpp @@ -0,0 +1,28 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <gtest/gtest.h> + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp b/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp new file mode 100644 index 000000000..9257ec918 --- /dev/null +++ b/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp @@ -0,0 +1,59 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <gtest/gtest.h> + +#include <metacall/metacall.h> +#include <metacall/metacall_loaders.h> + +class metacall_configuration_exec_relative_path_test : public testing::Test +{ +public: +}; + +TEST_F(metacall_configuration_exec_relative_path_test, DefaultConstructor) +{ + metacall_print_info(); + + ASSERT_EQ((int)0, (int)metacall_initialize()); + +/* Python */ +#if defined(OPTION_BUILD_LOADERS_PY) + { + const char *py_scripts[] = { + "main.py" + }; + + void *ret = NULL; + + ASSERT_EQ((int)0, (int)metacall_load_from_file("py", py_scripts, sizeof(py_scripts) / sizeof(py_scripts[0]), NULL)); + + ret = metacall("main"); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Python hello_world: test")); + + metacall_value_destroy(ret); + } +#endif /* OPTION_BUILD_LOADERS_PY */ + + metacall_destroy(); +} From 46e4fddd0eee0f538d31c7ccdc5e69478873ca9d Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 9 Jul 2025 17:05:34 +0200 Subject: [PATCH 061/109] Update rs_port version. --- source/ports/rs_port/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index 25789507b..d1030b99d 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" name = "metacall" readme = "README.md" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" -version = "0.4.2" +version = "0.4.3" [lib] crate-type = ["lib"] From 1001fcd8bb1445d96d1f69c71cf5a788bcf35bfa Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 9 Jul 2025 17:09:32 +0200 Subject: [PATCH 062/109] Update version to v0.9.13. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bf1ba0c17..6af8ded76 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.12 \ No newline at end of file +0.9.13 \ No newline at end of file From cd8a068ca7a2af4bd288f5fe5456a603b85237e4 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 15:13:45 +0200 Subject: [PATCH 063/109] Solve wrong error message location. --- source/configuration/source/configuration_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/configuration/source/configuration_object.c b/source/configuration/source/configuration_object.c index e49e8a733..8d5ec4584 100644 --- a/source/configuration/source/configuration_object.c +++ b/source/configuration/source/configuration_object.c @@ -104,8 +104,6 @@ configuration configuration_object_initialize(const char *name, const char *path if (config->source == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Failed to load configuration %s from %s", name, path); - free(config); return NULL; @@ -268,6 +266,8 @@ int configuration_object_childs(configuration config, vector childs, set storage if (child == NULL) { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load configuration %s from %s", (char *)key, path); + return 1; } From 51701a47cc51b86b78f1b9ed27b568f674952891 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 19:38:43 +0200 Subject: [PATCH 064/109] Add error generation (throwable). --- .../include/metacall/metacall_error.h | 24 +++++++++++++ source/metacall/source/metacall_error.c | 35 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/source/metacall/include/metacall/metacall_error.h b/source/metacall/include/metacall/metacall_error.h index ae030b965..e17815fbc 100644 --- a/source/metacall/include/metacall/metacall_error.h +++ b/source/metacall/include/metacall/metacall_error.h @@ -49,6 +49,30 @@ typedef struct metacall_exception_type *metacall_exception; /* -- Methods -- */ +/** +* @brief +* Create an throwable value from an exception with a simple API in a single instruction +* +* @param[in] label +* Label of the exception +* +* @param[in] code +* Error code of the exception +* +* @param[in] stacktrace +* Stack trace of the exception +* +* @param[in] message +* Message of the exception to be formatted with the variable arguments +* +* @param[in] va_args +* Arguments for formatting the message +* +* @return +* The value of type throwable containing the exception created +*/ +METACALL_API void *metacall_error_throw(const char *label, int64_t code, const char *stacktrace, const char *message, ...); + /** * @brief * Retrieve the exception from a value, it can be either a throwable value with an exception inside or an exception itself diff --git a/source/metacall/source/metacall_error.c b/source/metacall/source/metacall_error.c index 4bceddc72..68829a5ab 100644 --- a/source/metacall/source/metacall_error.c +++ b/source/metacall/source/metacall_error.c @@ -28,6 +28,41 @@ /* -- Methods -- */ +void *metacall_error_throw(const char *label, int64_t code, const char *stacktrace, const char *message, ...) +{ + va_list args, args_copy; + int length; + char *buffer; + exception ex; + throwable th; + + va_start(args, message); + va_copy(args_copy, args); + length = vsnprintf(NULL, 0, message, args_copy); + va_end(args_copy); + + if (length < 0) + { + va_end(args); + return NULL; /* TODO: Return a generic static error here */ + } + + buffer = malloc(length + 1); + + if (!buffer) + { + va_end(args); + return NULL; /* TODO: Return a generic static error here */ + } + + vsnprintf(buffer, length + 1, message, args); + va_end(args); + + ex = exception_create_message_const(buffer, label, code, stacktrace); + th = throwable_create(value_create_exception(ex)); + return value_create_throwable(th); +} + int metacall_error_from_value(void *v, metacall_exception ex) { if (v == NULL || ex == NULL) From c722edd16aeca5cbcc0bc12bc4ba69d1ef035336 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 19:40:38 +0200 Subject: [PATCH 065/109] Add exception facility for errors. --- .../include/reflect/reflect_exception.h | 2 + source/reflect/source/reflect_exception.c | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/source/reflect/include/reflect/reflect_exception.h b/source/reflect/include/reflect/reflect_exception.h index 81ff9a3a8..476bb417b 100644 --- a/source/reflect/include/reflect/reflect_exception.h +++ b/source/reflect/include/reflect/reflect_exception.h @@ -37,6 +37,8 @@ REFLECT_API exception exception_create(char *message, char *label, int64_t code, REFLECT_API exception exception_create_const(const char *message, const char *label, int64_t code, const char *stacktrace); +REFLECT_API exception exception_create_message_const(char *message, const char *label, int64_t code, const char *stacktrace); + REFLECT_API int exception_increment_reference(exception ex); REFLECT_API int exception_decrement_reference(exception ex); diff --git a/source/reflect/source/reflect_exception.c b/source/reflect/source/reflect_exception.c index 34b3dc2d3..7a85d46b0 100644 --- a/source/reflect/source/reflect_exception.c +++ b/source/reflect/source/reflect_exception.c @@ -153,6 +153,73 @@ exception exception_create_const(const char *message, const char *label, int64_t return NULL; } +exception exception_create_message_const(char *message, const char *label, int64_t code, const char *stacktrace) +{ + exception ex = malloc(sizeof(struct exception_type)); + + if (ex == NULL) + { + goto exception_bad_alloc; + } + + ex->message = message; + + if (label != NULL) + { + size_t label_size = strlen(label) + 1; + + ex->label = malloc(sizeof(char) * label_size); + + if (ex->label == NULL) + { + goto label_bad_alloc; + } + + memcpy(ex->label, label, label_size); + } + else + { + ex->label = NULL; + } + + if (stacktrace != NULL) + { + size_t stacktrace_size = strlen(stacktrace) + 1; + + ex->stacktrace = malloc(sizeof(char) * stacktrace_size); + + if (ex->stacktrace == NULL) + { + goto stacktrace_bad_alloc; + } + + memcpy(ex->stacktrace, stacktrace, stacktrace_size); + } + else + { + ex->stacktrace = NULL; + } + + ex->code = code; + ex->id = thread_id_get_current(); + + threading_atomic_ref_count_initialize(&ex->ref); + + reflect_memory_tracker_allocation(exception_stats); + + return ex; + +stacktrace_bad_alloc: + if (ex->label != NULL) + { + free(ex->label); + } +label_bad_alloc: + free(ex); +exception_bad_alloc: + return NULL; +} + int exception_increment_reference(exception ex) { if (ex == NULL) From abf23518c4506dea81030d0294dabe3f7b62c09f Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 19:40:55 +0200 Subject: [PATCH 066/109] Solve issues with metacall values. --- source/reflect/source/reflect_value_type.c | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/source/reflect/source/reflect_value_type.c b/source/reflect/source/reflect_value_type.c index 6775aac44..cc5692161 100644 --- a/source/reflect/source/reflect_value_type.c +++ b/source/reflect/source/reflect_value_type.c @@ -525,15 +525,29 @@ value value_from_double(value v, double d) value value_from_string(value v, const char *str, size_t length) { - if (v != NULL && str != NULL && length > 0) + if (v != NULL) { - size_t current_size = value_size(v); + if (str == NULL || length == 0) + { + return value_from(v, NULL, 1); + } + else + { + size_t current_size = value_type_size(v); - size_t bytes = length + 1; + size_t bytes = length + 1; - size_t size = (bytes <= current_size) ? bytes : current_size; + size_t size = (bytes <= current_size) ? bytes : current_size; - return value_from(v, str, size); + value_from(v, str, size); + + if (bytes > current_size) + { + char *str = value_to_string(v); + + str[size - 1] = '\0'; + } + } } return v; @@ -543,7 +557,7 @@ value value_from_buffer(value v, const void *buffer, size_t size) { if (v != NULL && buffer != NULL && size > 0) { - size_t current_size = value_size(v); + size_t current_size = value_type_size(v); size_t bytes = sizeof(char) * size; @@ -557,7 +571,7 @@ value value_from_array(value v, const value *values, size_t size) { if (v != NULL && values != NULL && size > 0) { - size_t current_size = value_size(v); + size_t current_size = value_type_size(v); size_t bytes = sizeof(const value) * size; @@ -571,7 +585,7 @@ value value_from_map(value v, const value *tuples, size_t size) { if (v != NULL && tuples != NULL && size > 0) { - size_t current_size = value_size(v); + size_t current_size = value_type_size(v); size_t bytes = sizeof(const value) * size; From b6054cee5d044e7ad29509357995bd40749a806e Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 19:41:48 +0200 Subject: [PATCH 067/109] Improve C loader with more types and issues. --- .../loaders/c_loader/source/c_loader_impl.cpp | 107 ++++++++++++++++-- source/scripts/c/compiled/source/compiled.c | 101 +++++++++++++++++ source/scripts/c/loadtest/source/loadtest.cpp | 4 + source/scripts/c/loadtest/source/loadtest.h | 2 +- 4 files changed, 203 insertions(+), 11 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index a4e57914c..d1ef1cb78 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -55,6 +55,7 @@ namespace fs = std::experimental::filesystem; #include <string> #include <vector> +#include <cassert> #include <cstring> /* LibFFI */ @@ -633,10 +634,18 @@ ffi_type *c_loader_impl_ffi_type(type_id id) return &ffi_type_float; case TYPE_DOUBLE: return &ffi_type_double; + case TYPE_STRING: + return &ffi_type_pointer; + case TYPE_BUFFER: + return &ffi_type_pointer; + case TYPE_ARRAY: + return &ffi_type_pointer; case TYPE_PTR: return &ffi_type_pointer; case TYPE_FUNCTION: return &ffi_type_pointer; + case TYPE_NULL: + return &ffi_type_void; } return &ffi_type_void; @@ -648,8 +657,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f if (args_size != signature_count(s)) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid number of arguments when calling %s (canceling call in order to avoid a segfault)", function_name(func)); - return NULL; + return metacall_error_throw("C Loader Error", 0, "", "Invalid number of arguments when calling %s (canceling call in order to avoid a segfault)", function_name(func)); } loader_impl_c_function c_function = static_cast<loader_impl_c_function>(impl); @@ -663,7 +671,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f if (id != value_id) { - log_write("metacall", LOG_LEVEL_ERROR, + return metacall_error_throw("C Loader Error", 0, "", "Type mismatch in when calling %s in argument number %" PRIuS " (expected %s of type %s and received %s)." " Canceling call in order to avoid a segfault.", @@ -672,7 +680,6 @@ function_return function_c_interface_invoke(function func, function_impl impl, f type_name(t), type_id_name(id), type_id_name(value_id)); - return NULL; } if (id == TYPE_FUNCTION) @@ -683,19 +690,39 @@ function_return function_c_interface_invoke(function func, function_impl impl, f closures.push_back(closure); } - else + else if (id == TYPE_STRING || id == TYPE_BUFFER || id == TYPE_ARRAY || id == TYPE_PTR) { + /* + String, buffer requires to be pointer to a string + Array requires to be pointer to a array + Pointer requires to be pointer to pointer + */ + + /* In order to work, this must be true */ + assert(args[args_count] == value_data(args[args_count])); + + c_function->values[args_count] = (void *)&args[args_count]; + } + else if (type_id_integer(id) == 0 || type_id_decimal(id) == 0) + { + /* Primitive types already have the pointer indirection */ c_function->values[args_count] = value_data((value)args[args_count]); } + else + { + return metacall_error_throw("C Loader Error", 0, "", + "Type %s in argument number %" PRIuS " of function %s is not supported.", + type_id_name(id), + args_count, + function_name(func)); + } } type_id ret_id = type_index(signature_get_return(s)); size_t ret_size = value_type_id_size(ret_id); void *ret = NULL; - /* TODO: This if is not correct because the sizes of strings, objects, etc are - relative to the pointer, not the value contents, we should review this */ - if (ret_size <= sizeof(ffi_arg)) + if (ret_size <= sizeof(ffi_arg) && (type_id_integer(ret_id) == 0 || type_id_decimal(ret_id) == 0)) { ffi_arg result; @@ -705,9 +732,50 @@ function_return function_c_interface_invoke(function func, function_impl impl, f } else { - ret = value_type_create(NULL, ret_size, ret_id); + void *result = NULL; + void *result_ptr = &result; + + if (ret_id == TYPE_NULL) + { + ret = value_create_null(); + result_ptr = NULL; + } + else if (ret_id != TYPE_STRING && ret_id != TYPE_BUFFER && ret_id != TYPE_ARRAY && ret_id != TYPE_PTR) + { + /* TODO: This is not tested and we do not know how to handle it */ + /* TODO: result = ret = value_type_create(NULL, ret_size, ret_id); */ + + return metacall_error_throw("C Loader Error", 0, "", + "Return type %s in of function %s is not supported.", + type_id_name(ret_id), + function_name(func)); + } - ffi_call(&c_function->cif, FFI_FN(c_function->address), value_data(ret), c_function->values); + ffi_call(&c_function->cif, FFI_FN(c_function->address), result_ptr, c_function->values); + + if (ret_id == TYPE_STRING) + { + char *str = (char *)result; + ret = value_create_string(str, strlen(str)); + } + else if (ret_id == TYPE_BUFFER) + { + return metacall_error_throw("C Loader Error", 0, "", + "Return type %s in of function %s is not supported, buffer is unsafe to be returned because there is no way to reconstruct it without overflowing as there is no null character nor size information.", + type_id_name(ret_id), + function_name(func)); + } + else if (ret_id == TYPE_ARRAY) + { + return metacall_error_throw("C Loader Error", 0, "", + "Return type %s in of function %s is not supported, array is unsafe to be returned because there is no way to reconstruct it without overflowing as there is no null character nor size information.", + type_id_name(ret_id), + function_name(func)); + } + else if (ret_id == TYPE_PTR) + { + ret = value_create_ptr(result); + } } /* Clear allocated closures if any */ @@ -800,6 +868,7 @@ int c_loader_impl_initialize_types(loader_impl impl) { TYPE_BOOL, "bool" }, { TYPE_CHAR, "char" }, + { TYPE_CHAR, "unsigned char" }, { TYPE_CHAR, "int8_t" }, { TYPE_CHAR, "uint8_t" }, { TYPE_CHAR, "int_least8_t" }, @@ -808,6 +877,7 @@ int c_loader_impl_initialize_types(loader_impl impl) { TYPE_CHAR, "uint_fast8_t" }, { TYPE_SHORT, "short" }, + { TYPE_SHORT, "unsigned short" }, { TYPE_SHORT, "int16_t" }, { TYPE_SHORT, "uint16_t" }, { TYPE_SHORT, "int_least16_t" }, @@ -816,6 +886,7 @@ int c_loader_impl_initialize_types(loader_impl impl) { TYPE_SHORT, "uint_fast16_t" }, { TYPE_INT, "int" }, + { TYPE_INT, "unsigned int" }, { TYPE_INT, "uint32_t" }, { TYPE_INT, "int32_t" }, { TYPE_INT, "int_least32_t" }, @@ -824,7 +895,9 @@ int c_loader_impl_initialize_types(loader_impl impl) { TYPE_INT, "uint_fast32_t" }, { TYPE_LONG, "long" }, + { TYPE_LONG, "unsigned long" }, { TYPE_LONG, "long long" }, + { TYPE_LONG, "unsigned long long" }, { TYPE_LONG, "uint64_t" }, { TYPE_LONG, "int64_t" }, { TYPE_LONG, "int_least64_t" }, @@ -838,6 +911,11 @@ int c_loader_impl_initialize_types(loader_impl impl) { TYPE_FLOAT, "float" }, { TYPE_DOUBLE, "double" }, + { TYPE_STRING, "unsigned char *" }, + { TYPE_STRING, "char *" }, + { TYPE_STRING, "const unsigned char *" }, + { TYPE_STRING, "const char *" }, + { TYPE_NULL, "void" } /* TODO: Do more types */ @@ -932,6 +1010,10 @@ static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXTyp return TYPE_PTR; } + case CXType_ConstantArray: + case CXType_IncompleteArray: + return TYPE_ARRAY; + case CXType_FunctionProto: case CXType_FunctionNoProto: { c_loader_closure_type *closure_type = new c_loader_closure_type(impl); @@ -964,7 +1046,12 @@ static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXTyp case CXType_Bool: return TYPE_BOOL; + case CXType_Short: + case CXType_UShort: + return TYPE_SHORT; + case CXType_Int: + case CXType_UInt: return TYPE_INT; case CXType_Void: diff --git a/source/scripts/c/compiled/source/compiled.c b/source/scripts/c/compiled/source/compiled.c index b7468cde7..e41807a41 100644 --- a/source/scripts/c/compiled/source/compiled.c +++ b/source/scripts/c/compiled/source/compiled.c @@ -1,4 +1,7 @@ +#include <assert.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> void compiled_print(int a, double b) { @@ -9,3 +12,101 @@ long compiled_sum(long a, long b) { return a + b; } + +char *return_text(void) +{ + static char input[] = "hello"; + return input; +} + +void process_text(char *input) +{ + printf("inside of compiled script '%s'\n", input); + assert(strcmp(input, "test_test") == 0); +} + +typedef struct data_t +{ + int value; +} * data_ptr_t; + +data_ptr_t alloc_data(void) +{ + data_ptr_t ptr = malloc(sizeof(struct data_t)); + + ptr->value = 0; + + printf("alloc_data %p\n", ptr); + + return ptr; +} + +void alloc_data_args(data_ptr_t *ptr) +{ + *ptr = malloc(sizeof(struct data_t)); + + (*ptr)->value = 0; + + printf("alloc_data_args %p\n", *ptr); + printf("alloc_data_args ref %p\n", ptr); +} + +int compare_data_value(data_ptr_t left, data_ptr_t right) +{ + printf("left %p\n", left); + printf("right %p\n", right); + assert(left == right); + return left == right; +} + +void set_data_value(data_ptr_t ptr, int value) +{ + printf("set_data_value %p\n", ptr); + ptr->value = value; +} + +int get_data_value(data_ptr_t ptr) +{ + printf("get_data_value %p\n", ptr); + return ptr->value; +} + +void free_data(data_ptr_t ptr) +{ + printf("free_data %p\n", ptr); + free(ptr); +} + +// TODO: When calling from NodeJS it does not work, +// NodeJS emmits double as a call, and this expects long, it needs a casting +void modify_int_ptr(long *l) +{ + printf("l %p\n", l); + printf("value %d\n", *l); + assert(*l == 324444L); + *l = 111L; +} + +void modify_double_ptr(double *d) +{ + printf("d %p\n", d); + printf("value %f\n", *d); + assert(*d == 324444.0); + *d = 111.0; +} + +void modify_str_ptr(char **str_ptr) +{ + static char new_str[] = "yeet"; + printf("(C) pointer %p\n", str_ptr); + printf("(C) string %p\n", (*str_ptr)); + printf("(C) string value %s\n", *str_ptr); + fflush(stdout); + assert(strcmp("asd", *str_ptr) == 0); + *str_ptr = new_str; + printf("(C) pointer %p\n", str_ptr); + printf("(C) string %p\n", (*str_ptr)); + printf("(C) string value %s\n", *str_ptr); + fflush(stdout); + assert(strcmp("yeet", *str_ptr) == 0); +} diff --git a/source/scripts/c/loadtest/source/loadtest.cpp b/source/scripts/c/loadtest/source/loadtest.cpp index 8dcb43ded..5ddaf4b11 100644 --- a/source/scripts/c/loadtest/source/loadtest.cpp +++ b/source/scripts/c/loadtest/source/loadtest.cpp @@ -1,4 +1,5 @@ #include "loadtest.h" +#include <iostream> #include <vector> long call_cpp_func(void) @@ -23,6 +24,9 @@ int pair_list_init(pair_list **t) (*t)->pairs[i].d = (double)(((double)i) * 1.0); } + std::cout << "pair_list_init: " << t << std::endl; + std::cout << "pair_list_init: *(" << *t << ")" << std::endl; + return 0; } diff --git a/source/scripts/c/loadtest/source/loadtest.h b/source/scripts/c/loadtest/source/loadtest.h index 3e4f07274..4a9335695 100644 --- a/source/scripts/c/loadtest/source/loadtest.h +++ b/source/scripts/c/loadtest/source/loadtest.h @@ -11,7 +11,7 @@ extern "C" { #endif -#include <cstdint> +#include <stdint.h> typedef struct { From 10df5e1e50b6fb9d7a29ca249cbddce71b7a3c97 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 28 Aug 2025 19:42:07 +0200 Subject: [PATCH 068/109] Solve issues with pointers in node loader. --- source/loaders/node_loader/source/node_loader_impl.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source/loaders/node_loader/source/node_loader_impl.cpp b/source/loaders/node_loader/source/node_loader_impl.cpp index e12594884..b493d1964 100644 --- a/source/loaders/node_loader/source/node_loader_impl.cpp +++ b/source/loaders/node_loader/source/node_loader_impl.cpp @@ -1442,14 +1442,13 @@ value node_loader_impl_napi_to_value(loader_impl_node node_impl, napi_env env, n } else if (valuetype == napi_external) { - /* Returns the previously allocated copy */ void *c = nullptr; status = napi_get_value_external(env, v, &c); node_loader_impl_exception(env, status); - return c; + return value_create_ptr(c); } return ret; @@ -1635,10 +1634,7 @@ napi_value node_loader_impl_value_to_napi(loader_impl_node node_impl, napi_env e } else if (id == TYPE_PTR) { - /* Copy value and set the ownership, the old value will be deleted after the call */ - void *c = value_copy(arg_value); - - value_move(arg_value, c); + void *c = value_to_ptr(arg_value); status = napi_create_external(env, c, nullptr, nullptr, &v); From 703d33648e84f08400166aa6d9537809053b9ca8 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 29 Aug 2025 18:10:41 +0200 Subject: [PATCH 069/109] Add support for array by value. --- .../loaders/c_loader/source/c_loader_impl.cpp | 132 +++++++++++++++++- source/scripts/c/compiled/source/compiled.c | 31 ++++ .../source/metacall_c_test.cpp | 64 +++++++++ 3 files changed, 222 insertions(+), 5 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index d1ef1cb78..d2cfefed1 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -517,6 +517,95 @@ class c_loader_closure_value } }; +static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXType cx_type, c_loader_type_impl **impl_type); + +class c_loader_array_type : public c_loader_type_impl +{ +public: + std::optional<long long> size; + type_id id; + + c_loader_array_type(loader_impl impl, CXCursor cursor, CXType cx_type, c_loader_type_impl **impl_type) + { + CXType element_cx_type = clang_getArrayElementType(cx_type); + + id = c_loader_impl_clang_type(impl, cursor, element_cx_type, impl_type); + + if (cx_type.kind == CXType_ConstantArray) + { + size = clang_getArraySize(cx_type); + + if (size < 0) + { + size = 0; + } + } + } + + ~c_loader_array_type() {} + + void *generate_c_array(void *array, size_t args_count, function func, void **error) + { + size_t count = metacall_value_count(array); + + /* Check if array size is correct */ + if (size.has_value()) + { + if (count != static_cast<size_t>(*size)) + { + *error = metacall_error_throw("C Loader Error", 0, "", "Argument %" PRIuS " of type array with different size when calling %s (expecting an array of size %d, received an array of size %" PRIuS ")", args_count, function_name(func), *size, count); + return NULL; + } + } + + /* Check if array type is correct */ + void **array_ptr = metacall_value_to_array(array); + + for (size_t it = 0; it < count; ++it) + { + if (metacall_value_id(array_ptr[it]) != id) + { + *error = metacall_error_throw("C Loader Error", 0, "", "Argument %" PRIuS " of type array with different type when calling %s (expecting an array of type %s, received an array of type %s in the element %" PRIuS ")", args_count, function_name(func), type_id_name(id), metacall_value_type_name(array_ptr[it]), it); + return NULL; + } + } + + /* Allocate temporal memory */ + size_t type_size = value_type_id_size(id); + void **memory_ptr = static_cast<void **>(malloc(sizeof(void **))); + + if (memory_ptr == NULL) + { + *error = metacall_error_throw("C Loader Error", 0, "", "Argument %" PRIuS " failed to allocate memory pointer for the array when calling %s", args_count, function_name(func)); + return NULL; + } + + void *memory = malloc(count * type_size); + + if (memory == NULL) + { + *error = metacall_error_throw("C Loader Error", 0, "", "Argument %" PRIuS " failed to allocate memory for the array when calling %s", args_count, function_name(func)); + free(memory_ptr); + return NULL; + } + + for (size_t it = 0; it < count; ++it) + { + std::memcpy(&((unsigned char *)memory)[it * type_size], array_ptr[it], type_size); + } + + *memory_ptr = memory; + + return memory_ptr; + } + + static void free_c_array(void **memory_ptr) + { + free(*memory_ptr); + free(memory_ptr); + } +}; + std::string c_loader_impl_cxstring_to_str(const CXString &s) { std::string result = clang_getCString(s); @@ -690,11 +779,10 @@ function_return function_c_interface_invoke(function func, function_impl impl, f closures.push_back(closure); } - else if (id == TYPE_STRING || id == TYPE_BUFFER || id == TYPE_ARRAY || id == TYPE_PTR) + else if (id == TYPE_STRING || id == TYPE_BUFFER || id == TYPE_PTR) { /* String, buffer requires to be pointer to a string - Array requires to be pointer to a array Pointer requires to be pointer to pointer */ @@ -703,6 +791,19 @@ function_return function_c_interface_invoke(function func, function_impl impl, f c_function->values[args_count] = (void *)&args[args_count]; } + else if (id == TYPE_ARRAY) + { + c_loader_array_type *array = static_cast<c_loader_array_type *>(type_derived(t)); + void *error = NULL; + void *array_ptr = array->generate_c_array(args[args_count], args_count, func, &error); + + if (error != NULL) + { + return error; + } + + c_function->values[args_count] = array_ptr; + } else if (type_id_integer(id) == 0 || type_id_decimal(id) == 0) { /* Primitive types already have the pointer indirection */ @@ -778,6 +879,17 @@ function_return function_c_interface_invoke(function func, function_impl impl, f } } + for (size_t args_count = 0; args_count < args_size; ++args_count) + { + type t = signature_get_type(s, args_count); + type_id id = type_index(t); + + if (id == TYPE_ARRAY) + { + c_loader_array_type::free_c_array(static_cast<void **>(c_function->values[args_count])); + } + } + /* Clear allocated closures if any */ for (c_loader_closure_value *closure : closures) { @@ -984,7 +1096,7 @@ int c_loader_impl_execution_path(loader_impl impl, const loader_path path) return 0; } -static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXType cx_type, c_loader_type_impl **impl_type) +type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXType cx_type, c_loader_type_impl **impl_type) { switch (cx_type.kind) { @@ -1011,8 +1123,18 @@ static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXTyp } case CXType_ConstantArray: - case CXType_IncompleteArray: - return TYPE_ARRAY; + case CXType_IncompleteArray: { + c_loader_array_type *array_type = new c_loader_array_type(impl, cursor, cx_type, impl_type); + + if (array_type != nullptr) + { + *impl_type = static_cast<c_loader_array_type *>(array_type); + + return TYPE_ARRAY; + } + + return TYPE_INVALID; + } case CXType_FunctionProto: case CXType_FunctionNoProto: { diff --git a/source/scripts/c/compiled/source/compiled.c b/source/scripts/c/compiled/source/compiled.c index e41807a41..c8e33e9d9 100644 --- a/source/scripts/c/compiled/source/compiled.c +++ b/source/scripts/c/compiled/source/compiled.c @@ -77,6 +77,37 @@ void free_data(data_ptr_t ptr) free(ptr); } +/* https://github.com/metacall/core/issues/570 */ +void apply_blur_filter(int pixels[], int width, int height) +{ + int size = width * height; + + printf("pixels == %p\n", pixels); + fflush(stdout); + + for (int i = 0; i < size; i++) + { + printf("pixels[%d] == %d\n", pixels[i], i); + fflush(stdout); + assert(pixels[i] == i); + pixels[i] = pixels[i] / 2; + } + printf("C: Blur filter applied on %d pixels\n", size); +} + +double calculate_brightness(int pixels[], int size) +{ + long sum = 0; + for (int i = 0; i < size; i++) + { + assert(pixels[i] == i); + sum += pixels[i]; + } + double avg = (double)sum / (double)size; + printf("C: Average brightness = %f\n", avg); + return avg; +} + // TODO: When calling from NodeJS it does not work, // NodeJS emmits double as a call, and this expects long, it needs a casting void modify_int_ptr(long *l) diff --git a/source/tests/metacall_c_test/source/metacall_c_test.cpp b/source/tests/metacall_c_test/source/metacall_c_test.cpp index 46cce764e..2721c469c 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -60,6 +60,70 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_value_destroy(ret); + /* https://github.com/metacall/core/issues/570 */ + { + /* Call by array */ + { + void *args[] = { + metacall_value_create_array(NULL, 100), + metacall_value_create_int(10), + metacall_value_create_int(10) + }; + + void **array_ptr = metacall_value_to_array(args[0]); + + for (int i = 0; i < 100; ++i) + { + array_ptr[i] = metacall_value_create_int(i); + } + + std::cout << "value: " << args[0] << std::endl; + std::cout << "array: " << array_ptr << std::endl; + + ret = metacallv("apply_blur_filter", args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + + metacall_value_destroy(args[0]); + metacall_value_destroy(args[1]); + metacall_value_destroy(args[2]); + } + + /* Call by pointer */ + { + int array[100]; + + void *args[] = { + metacall_value_create_ptr(array), + metacall_value_create_int(10), + metacall_value_create_int(10) + }; + + for (int i = 0; i < 100; ++i) + { + array[i] = i; + } + + ret = metacallv("apply_blur_filter", args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + + metacall_value_destroy(args[0]); + metacall_value_destroy(args[1]); + metacall_value_destroy(args[2]); + } + + // TODO: double calculate_brightness(int pixels[], int size) + } + /* File with dependencies */ const char *c_dep_scripts[] = { "ffi.c", From 0a313d25ebca4d8e795117228637e0d1e6cb7557 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 2 Sep 2025 17:24:20 +0200 Subject: [PATCH 070/109] Improve C loader ptr and tests. --- .../loaders/c_loader/source/c_loader_impl.cpp | 12 +- source/scripts/c/loadtest/source/loadtest.cpp | 4 + .../source/metacall_c_lib_test.cpp | 17 ++- .../source/metacall_c_test.cpp | 104 ++++++++++++++++++ 4 files changed, 126 insertions(+), 11 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index d2cfefed1..bb712d5ad 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -52,6 +52,7 @@ namespace fs = std::experimental::filesystem; #endif #include <map> +#include <optional> #include <string> #include <vector> @@ -779,18 +780,19 @@ function_return function_c_interface_invoke(function func, function_impl impl, f closures.push_back(closure); } - else if (id == TYPE_STRING || id == TYPE_BUFFER || id == TYPE_PTR) + else if (id == TYPE_STRING || id == TYPE_BUFFER) { - /* - String, buffer requires to be pointer to a string - Pointer requires to be pointer to pointer - */ + /* String, buffer requires to be pointer to a string */ /* In order to work, this must be true */ assert(args[args_count] == value_data(args[args_count])); c_function->values[args_count] = (void *)&args[args_count]; } + else if (id == TYPE_PTR) + { + c_function->values[args_count] = args[args_count]; + } else if (id == TYPE_ARRAY) { c_loader_array_type *array = static_cast<c_loader_array_type *>(type_derived(t)); diff --git a/source/scripts/c/loadtest/source/loadtest.cpp b/source/scripts/c/loadtest/source/loadtest.cpp index 5ddaf4b11..3bc2b6328 100644 --- a/source/scripts/c/loadtest/source/loadtest.cpp +++ b/source/scripts/c/loadtest/source/loadtest.cpp @@ -13,6 +13,9 @@ int pair_list_init(pair_list **t) { static const uint32_t size = 3; + std::cout << "pair_list_init: " << t << std::endl; + std::cout << "pair_list_init: *(" << *t << ")" << std::endl; + *t = new pair_list(); (*t)->size = size; @@ -37,6 +40,7 @@ double pair_list_value(pair_list *t, uint32_t id) void pair_list_destroy(pair_list *t) { + std::cout << "pair_list_destroy: *(" << t << ")" << std::endl; delete[] t->pairs; delete t; } diff --git a/source/tests/metacall_c_lib_test/source/metacall_c_lib_test.cpp b/source/tests/metacall_c_lib_test/source/metacall_c_lib_test.cpp index cabe0100b..1f61c2b17 100644 --- a/source/tests/metacall_c_lib_test/source/metacall_c_lib_test.cpp +++ b/source/tests/metacall_c_lib_test/source/metacall_c_lib_test.cpp @@ -43,14 +43,20 @@ TEST_F(metacall_c_lib_test, DefaultConstructor) metacall_value_destroy(ret); - void *pair_list = NULL; + void *pair_list_ptr = metacall_value_create_ptr(NULL); void *args_init[] = { - metacall_value_create_ptr(&pair_list), + metacall_value_create_ptr(pair_list_ptr), }; + std::cout << "pair_list_ptr: " << pair_list_ptr << std::endl; + std::cout << "pair_list_ptr: *(" << metacall_value_to_ptr(pair_list_ptr) << ")" << std::endl; + ret = metacallv("pair_list_init", args_init); + std::cout << "pair_list_ptr: " << pair_list_ptr << std::endl; + std::cout << "pair_list_ptr: *(" << metacall_value_to_ptr(pair_list_ptr) << ")" << std::endl; + EXPECT_NE((void *)NULL, (void *)ret); EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_INT); @@ -62,7 +68,7 @@ TEST_F(metacall_c_lib_test, DefaultConstructor) metacall_value_destroy(args_init[0]); void *args_value[] = { - metacall_value_create_ptr(pair_list), + pair_list_ptr, metacall_value_create_int(2) }; @@ -76,11 +82,10 @@ TEST_F(metacall_c_lib_test, DefaultConstructor) metacall_value_destroy(ret); - metacall_value_destroy(args_value[0]); metacall_value_destroy(args_value[1]); void *args_destroy[] = { - metacall_value_create_ptr(pair_list), + pair_list_ptr, }; ret = metacallv("pair_list_destroy", args_destroy); @@ -91,7 +96,7 @@ TEST_F(metacall_c_lib_test, DefaultConstructor) metacall_value_destroy(ret); - metacall_value_destroy(args_destroy[0]); + metacall_value_destroy(pair_list_ptr); metacall_destroy(); } diff --git a/source/tests/metacall_c_test/source/metacall_c_test.cpp b/source/tests/metacall_c_test/source/metacall_c_test.cpp index 2721c469c..490428e15 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -41,6 +41,37 @@ void *sum_callback(size_t argc, void *args[], void *data) return metacall_value_create_int(result); } +void *test_string_reference(size_t argc, void *args[], void *data) +{ + printf("ptr %p\n", args[0]); + fflush(stdout); + + void *string_value = metacall_value_to_ptr(args[0]); + + printf("string ptr %p\n", string_value); + printf("type id %s\n", metacall_value_type_name(string_value)); + fflush(stdout); + + char *str = metacall_value_to_string(string_value); + + (void)argc; + (void)data; + + printf("native string %s\n", str); + + EXPECT_STREQ("asd", str); + + static const char yeet[] = "yeet"; + + metacall_value_from_string(string_value, yeet, sizeof(yeet) - 1); + + printf("type id %s\n", metacall_value_type_name(string_value)); + printf("native string %s\n", str); + fflush(stdout); + + return metacall_value_create_null(); +} + TEST_F(metacall_c_test, DefaultConstructor) { ASSERT_EQ((int)0, (int)metacall_initialize()); @@ -196,6 +227,79 @@ TEST_F(metacall_c_test, DefaultConstructor) // metacall_value_destroy(ret); + /* References (Native) */ + { + static const char str[] = "asd"; + void *str_value = metacall_value_create_string(str, sizeof(str) - 1); + void *str_value_ref = metacall_value_reference(str_value); + + printf("ptr %p\n", str_value_ref); + printf("string %p\n", str_value); + printf("string str %s\n", metacall_value_to_string(str_value)); + fflush(stdout); + + { + void *new_str_value = metacall_value_to_ptr(str_value_ref); + char *new_str = metacall_value_to_string(new_str_value); + + EXPECT_STREQ("asd", new_str); + } + + void *args[] = { + str_value_ref + }; + + metacall_register("test_string_reference", test_string_reference, NULL, METACALL_NULL, 1, METACALL_PTR); + + ret = metacallv_s("test_string_reference", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + + printf("type id %s\n", metacall_value_type_name(str_value)); + fflush(stdout); + + // It chops the string because it has a fixed size from 'asd' + EXPECT_STREQ(metacall_value_to_string(str_value), "yee"); + + metacall_value_destroy(str_value); + metacall_value_destroy(str_value_ref); + } + + /* References (C) */ + { + static const char str[] = "asd"; + void *str_value = metacall_value_create_string(str, sizeof(str) - 1); + void *str_value_ref = metacall_value_reference(str_value); + + printf("(R) ptr %p\n", str_value_ref); + printf("(R) string ptr %p\n", str_value); + printf("(R) string str %s\n", metacall_value_to_string(str_value)); + fflush(stdout); + + void *args[] = { + str_value_ref + }; + + ret = metacallv_s("modify_str_ptr", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + + char *str_value_deref = static_cast<char *>(metacall_value_dereference(str_value_ref)); + + EXPECT_STREQ(str_value_deref, "yeet"); + + metacall_value_destroy(str_value); + metacall_value_destroy(str_value_ref); + } + /* Print inspect information */ { size_t size = 0; From 55dbfb4402b49c5bd8c85b9ff8d1684e8bc555cf Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 2 Sep 2025 22:55:47 +0200 Subject: [PATCH 071/109] Improve pointer, array in C loader. --- .../loaders/c_loader/source/c_loader_impl.cpp | 80 ++++++++++++++++--- .../reflect/source/reflect_value_type_cast.c | 6 ++ .../source/metacall_c_test.cpp | 65 ++++++++++++++- 3 files changed, 141 insertions(+), 10 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index bb712d5ad..c041ffc5c 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -759,7 +759,8 @@ function_return function_c_interface_invoke(function func, function_impl impl, f type_id id = type_index(t); type_id value_id = value_type_id((value)args[args_count]); - if (id != value_id) + /* We can accept pointers if we pass to an array, it is unsafe but it improves efficiency */ + if (id != value_id && !(value_id == TYPE_PTR && id == TYPE_ARRAY)) { return metacall_error_throw("C Loader Error", 0, "", "Type mismatch in when calling %s in argument number %" PRIuS @@ -772,7 +773,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f type_id_name(value_id)); } - if (id == TYPE_FUNCTION) + if (value_id == TYPE_FUNCTION) { c_loader_closure_value *closure = new c_loader_closure_value(static_cast<c_loader_closure_type *>(type_derived(t))); @@ -780,7 +781,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f closures.push_back(closure); } - else if (id == TYPE_STRING || id == TYPE_BUFFER) + else if (value_id == TYPE_STRING || value_id == TYPE_BUFFER) { /* String, buffer requires to be pointer to a string */ @@ -789,11 +790,11 @@ function_return function_c_interface_invoke(function func, function_impl impl, f c_function->values[args_count] = (void *)&args[args_count]; } - else if (id == TYPE_PTR) + else if (value_id == TYPE_PTR) { c_function->values[args_count] = args[args_count]; } - else if (id == TYPE_ARRAY) + else if (value_id == TYPE_ARRAY) { c_loader_array_type *array = static_cast<c_loader_array_type *>(type_derived(t)); void *error = NULL; @@ -806,7 +807,7 @@ function_return function_c_interface_invoke(function func, function_impl impl, f c_function->values[args_count] = array_ptr; } - else if (type_id_integer(id) == 0 || type_id_decimal(id) == 0) + else if (type_id_integer(value_id) == 0 || type_id_decimal(value_id) == 0) { /* Primitive types already have the pointer indirection */ c_function->values[args_count] = value_data((value)args[args_count]); @@ -883,10 +884,9 @@ function_return function_c_interface_invoke(function func, function_impl impl, f for (size_t args_count = 0; args_count < args_size; ++args_count) { - type t = signature_get_type(s, args_count); - type_id id = type_index(t); + type_id value_id = value_type_id((value)args[args_count]); - if (id == TYPE_ARRAY) + if (value_id == TYPE_ARRAY) { c_loader_array_type::free_c_array(static_cast<void **>(c_function->values[args_count])); } @@ -1353,6 +1353,68 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas command_line_args.push_back(includes.back().c_str()); } + /* TODO: Load from memory (discover from memory) */ + /* + #include <clang-c/Index.h> + #include <stdio.h> + #include <stdlib.h> + + int main() { + const char *source_code = + "int add(int a, int b) {\n" + " return a + b;\n" + "}"; + + // Simulate an in-memory file + CXUnsavedFile unsaved_file; + unsaved_file.Filename = "example.c"; + unsaved_file.Contents = source_code; + unsaved_file.Length = (unsigned long)strlen(source_code); + + // Create index + CXIndex index = clang_createIndex(0, 0); + + // Parse translation unit from buffer (unsaved file) + CXTranslationUnit tu; + CXErrorCode err = clang_parseTranslationUnit2( + index, + "example.c", // filename for context (matches unsaved file) + NULL, 0, // command line args + &unsaved_file, 1, // unsaved files + CXTranslationUnit_None, // options + &tu + ); + + if (err != CXError_Success) { + fprintf(stderr, "Failed to parse translation unit.\n"); + return 1; + } + + // Get the cursor to the root of the translation unit + CXCursor cursor = clang_getTranslationUnitCursor(tu); + + // Visit each AST node + clang_visitChildren( + cursor, + [](CXCursor c, CXCursor parent, CXClientData client_data) { + CXString spelling = clang_getCursorSpelling(c); + CXString kind = clang_getCursorKindSpelling(clang_getCursorKind(c)); + printf("Cursor: %s (%s)\n", clang_getCString(spelling), clang_getCString(kind)); + clang_disposeString(spelling); + clang_disposeString(kind); + return CXChildVisit_Recurse; + }, + NULL + ); + + // Clean up + clang_disposeTranslationUnit(tu); + clang_disposeIndex(index); + + return 0; + } + */ + for (std::string file : c_handle->files) { /* Define the command line arguments (simulating compiler flags) */ diff --git a/source/reflect/source/reflect_value_type_cast.c b/source/reflect/source/reflect_value_type_cast.c index 7b7410da3..e7b667026 100644 --- a/source/reflect/source/reflect_value_type_cast.c +++ b/source/reflect/source/reflect_value_type_cast.c @@ -36,6 +36,12 @@ value value_type_cast(value v, type_id id) return v; } + /* Exception raised, avoid casting */ + if (type_id_throwable(src_id) == 0) + { + return v; + } + /* Cast from string to any type */ if (type_id_string(src_id) == 0) { diff --git a/source/tests/metacall_c_test/source/metacall_c_test.cpp b/source/tests/metacall_c_test/source/metacall_c_test.cpp index 490428e15..7aa43a950 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -93,6 +93,8 @@ TEST_F(metacall_c_test, DefaultConstructor) /* https://github.com/metacall/core/issues/570 */ { + /* void apply_blur_filter(int pixels[], int width, int height) */ + /* Call by array */ { void *args[] = { @@ -152,7 +154,68 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_value_destroy(args[2]); } - // TODO: double calculate_brightness(int pixels[], int size) + /* double calculate_brightness(int pixels[], int size) */ + + /* Call by array */ + { + void *args[] = { + metacall_value_create_array(NULL, 100), + metacall_value_create_int(100) + }; + + void **array_ptr = metacall_value_to_array(args[0]); + + for (int i = 0; i < 100; ++i) + { + array_ptr[i] = metacall_value_create_int(i); + } + + std::cout << "value: " << args[0] << std::endl; + std::cout << "array: " << array_ptr << std::endl; + + ret = metacallv("calculate_brightness", args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_DOUBLE); + + std::cout << "result: " << metacall_value_to_double(ret) << std::endl; + + EXPECT_EQ((double)metacall_value_to_double(ret), (double)49.5); + + metacall_value_destroy(ret); + + metacall_value_destroy(args[0]); + metacall_value_destroy(args[1]); + } + + /* Call by pointer */ + { + int array[100]; + + void *args[] = { + metacall_value_create_ptr(array), + metacall_value_create_int(100) + }; + + for (int i = 0; i < 100; ++i) + { + array[i] = i; + } + + ret = metacallv("calculate_brightness", args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_DOUBLE); + + std::cout << "result: " << metacall_value_to_double(ret) << std::endl; + + metacall_value_destroy(ret); + + metacall_value_destroy(args[0]); + metacall_value_destroy(args[1]); + } } /* File with dependencies */ From 9c9581bb288f24f8bc3b14cf4095d693020806a0 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 3 Sep 2025 17:13:00 +0200 Subject: [PATCH 072/109] Solve issues with tests. --- source/scripts/c/compiled/source/compiled.c | 4 ++ .../source/metacall_c_test.cpp | 59 +++++++++++++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/source/scripts/c/compiled/source/compiled.c b/source/scripts/c/compiled/source/compiled.c index c8e33e9d9..8493e28d9 100644 --- a/source/scripts/c/compiled/source/compiled.c +++ b/source/scripts/c/compiled/source/compiled.c @@ -114,6 +114,7 @@ void modify_int_ptr(long *l) { printf("l %p\n", l); printf("value %d\n", *l); + fflush(stdout); assert(*l == 324444L); *l = 111L; } @@ -122,6 +123,7 @@ void modify_double_ptr(double *d) { printf("d %p\n", d); printf("value %f\n", *d); + fflush(stdout); assert(*d == 324444.0); *d = 111.0; } @@ -130,7 +132,9 @@ void modify_str_ptr(char **str_ptr) { static char new_str[] = "yeet"; printf("(C) pointer %p\n", str_ptr); + fflush(stdout); printf("(C) string %p\n", (*str_ptr)); + fflush(stdout); printf("(C) string value %s\n", *str_ptr); fflush(stdout); assert(strcmp("asd", *str_ptr) == 0); diff --git a/source/tests/metacall_c_test/source/metacall_c_test.cpp b/source/tests/metacall_c_test/source/metacall_c_test.cpp index 7aa43a950..b661e8b39 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -43,6 +43,10 @@ void *sum_callback(size_t argc, void *args[], void *data) void *test_string_reference(size_t argc, void *args[], void *data) { + (void)argc; + (void)data; + + /* Get string from pointer */ printf("ptr %p\n", args[0]); fflush(stdout); @@ -54,13 +58,12 @@ void *test_string_reference(size_t argc, void *args[], void *data) char *str = metacall_value_to_string(string_value); - (void)argc; - (void)data; - printf("native string %s\n", str); + /* Check it is a valid string */ EXPECT_STREQ("asd", str); + /* Replace the string, it will be choped by the previous length */ static const char yeet[] = "yeet"; metacall_value_from_string(string_value, yeet, sizeof(yeet) - 1); @@ -69,6 +72,13 @@ void *test_string_reference(size_t argc, void *args[], void *data) printf("native string %s\n", str); fflush(stdout); + EXPECT_STREQ("yee", str); + + /* Define a new string in the pointer value */ + static const char hello[] = "hello world"; + + metacall_value_from_ptr(args[0], metacall_value_create_string(hello, sizeof(hello) - 1)); + return metacall_value_create_null(); } @@ -325,18 +335,26 @@ TEST_F(metacall_c_test, DefaultConstructor) printf("type id %s\n", metacall_value_type_name(str_value)); fflush(stdout); - // It chops the string because it has a fixed size from 'asd' + /* It chops the string because it has a fixed size from 'asd' */ EXPECT_STREQ(metacall_value_to_string(str_value), "yee"); metacall_value_destroy(str_value); + + /* It should contain the new string */ + void *new_str = metacall_value_dereference(str_value_ref); + + EXPECT_STREQ(metacall_value_to_string(new_str), "hello world"); + + metacall_value_destroy(new_str); metacall_value_destroy(str_value_ref); } - /* References (C) */ + /* References (C: string) */ { static const char str[] = "asd"; void *str_value = metacall_value_create_string(str, sizeof(str) - 1); void *str_value_ref = metacall_value_reference(str_value); + void *str_value_ref_ref = metacall_value_reference(str_value_ref); printf("(R) ptr %p\n", str_value_ref); printf("(R) string ptr %p\n", str_value); @@ -344,7 +362,7 @@ TEST_F(metacall_c_test, DefaultConstructor) fflush(stdout); void *args[] = { - str_value_ref + str_value_ref_ref }; ret = metacallv_s("modify_str_ptr", args, 1); @@ -361,6 +379,35 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_value_destroy(str_value); metacall_value_destroy(str_value_ref); + metacall_value_destroy(str_value_ref_ref); + } + + /* References (C: int) */ + { + void *int_value = metacall_value_create_long(324444L); + void *int_value_ref = metacall_value_reference(int_value); + + printf("(R) ptr %p\n", int_value_ref); + printf("(R) int ptr %p\n", int_value); + printf("(R) int value %ld\n", metacall_value_to_long(int_value)); + fflush(stdout); + + void *args[] = { + int_value_ref + }; + + ret = metacallv_s("modify_int_ptr", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + + EXPECT_EQ((long)metacall_value_to_long(int_value), (long)111L); + + metacall_value_destroy(int_value); + metacall_value_destroy(int_value_ref); } /* Print inspect information */ From 6b59246e6e9e5c1aaec4677d8bad0b2498b883e8 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 3 Sep 2025 17:13:58 +0200 Subject: [PATCH 073/109] Update bindings. --- source/ports/rs_port/src/bindings.rs | 1429 +------------------------- 1 file changed, 1 insertion(+), 1428 deletions(-) diff --git a/source/ports/rs_port/src/bindings.rs b/source/ports/rs_port/src/bindings.rs index 8f6385d5b..7222ae744 100644 --- a/source/ports/rs_port/src/bindings.rs +++ b/source/ports/rs_port/src/bindings.rs @@ -1,1430 +1,3 @@ /* automatically generated by rust-bindgen 0.71.1 */ -pub type __pid_t = ::std::os::raw::c_int; -pub type pid_t = __pid_t; -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum metacall_allocator_id { - METACALL_ALLOCATOR_STD = 0, - METACALL_ALLOCATOR_NGINX = 1, -} -unsafe extern "C" { - #[doc = " @brief\n Create an allocator instance\n\n @param[in] allocator_id\n Type of allocator to be created\n\n @param[in] ctx\n Context of the allocator\n\n @return\n Pointer to allocator if success, null otherwise"] - pub fn metacall_allocator_create( - allocator_id: metacall_allocator_id, - ctx: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Reserve memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] size\n Size in bytes to be allocated\n\n @return\n Pointer to allocated data on success, null otherwise"] - pub fn metacall_allocator_alloc( - allocator: *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Reallocate memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Original pointer to data\n\n @param[in] size\n Original size in bytes\n\n @param[in] new_size\n New size in bytes to be reallocated\n\n @return\n Pointer to new reallocated data on success, null otherwise"] - pub fn metacall_allocator_realloc( - allocator: *mut ::std::os::raw::c_void, - data: *mut ::std::os::raw::c_void, - size: usize, - new_size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Free memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Pointer to data to be freed"] - pub fn metacall_allocator_free( - allocator: *mut ::std::os::raw::c_void, - data: *mut ::std::os::raw::c_void, - ); -} -unsafe extern "C" { - #[doc = " @brief\n Destroy an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance"] - pub fn metacall_allocator_destroy(allocator: *mut ::std::os::raw::c_void); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct metacall_exception_type { - pub message: *const ::std::os::raw::c_char, - pub label: *const ::std::os::raw::c_char, - pub code: i64, - pub stacktrace: *const ::std::os::raw::c_char, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of metacall_exception_type"][::std::mem::size_of::<metacall_exception_type>() - 32usize]; - ["Alignment of metacall_exception_type"] - [::std::mem::align_of::<metacall_exception_type>() - 8usize]; - ["Offset of field: metacall_exception_type::message"] - [::std::mem::offset_of!(metacall_exception_type, message) - 0usize]; - ["Offset of field: metacall_exception_type::label"] - [::std::mem::offset_of!(metacall_exception_type, label) - 8usize]; - ["Offset of field: metacall_exception_type::code"] - [::std::mem::offset_of!(metacall_exception_type, code) - 16usize]; - ["Offset of field: metacall_exception_type::stacktrace"] - [::std::mem::offset_of!(metacall_exception_type, stacktrace) - 24usize]; -}; -pub type metacall_exception = *mut metacall_exception_type; -unsafe extern "C" { - #[doc = " @brief\n Retrieve the exception from a value, it can be either a throwable value with an exception inside or an exception itself\n\n @param[in] v\n Value that represents the exception to be retrieved\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to @v\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_error_from_value( - v: *mut ::std::os::raw::c_void, - ex: metacall_exception, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Retrieve last error that has happened after a call to any API from MetaCall\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to the internal MetaCall exception\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_error_last(ex: metacall_exception) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Clear last error that has happened after a call to any API from MetaCall"] - pub fn metacall_error_clear(); -} -unsafe extern "C" { - #[doc = " @brief\n Initialize link detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_link_initialize() -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_link_register( - tag: *const ::std::os::raw::c_char, - library: *const ::std::os::raw::c_char, - symbol: *const ::std::os::raw::c_char, - fn_: ::std::option::Option<unsafe extern "C" fn()>, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] loader\n Pointer to the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_link_register_loader( - loader: *mut ::std::os::raw::c_void, - library: *const ::std::os::raw::c_char, - symbol: *const ::std::os::raw::c_char, - fn_: ::std::option::Option<unsafe extern "C" fn()>, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Remove the hook previously registered\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_link_unregister( - tag: *const ::std::os::raw::c_char, - library: *const ::std::os::raw::c_char, - symbol: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Unregister link detours and destroy shared memory"] - pub fn metacall_link_destroy(); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum metacall_log_id { - METACALL_LOG_STDIO = 0, - METACALL_LOG_FILE = 1, - METACALL_LOG_SOCKET = 2, - METACALL_LOG_SYSLOG = 3, - METACALL_LOG_NGINX = 4, - METACALL_LOG_CUSTOM = 5, -} -unsafe extern "C" { - #[doc = " @brief\n Create a log instance\n\n @param[in] log_id\n Type of log to be created\n\n @param[in] ctx\n Context of the log (a pointer to metacall_log_{stdio, file, socket, syslog, nginx, custom}_type)\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_log( - log_id: metacall_log_id, - ctx: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum metacall_value_id { - METACALL_BOOL = 0, - METACALL_CHAR = 1, - METACALL_SHORT = 2, - METACALL_INT = 3, - METACALL_LONG = 4, - METACALL_FLOAT = 5, - METACALL_DOUBLE = 6, - METACALL_STRING = 7, - METACALL_BUFFER = 8, - METACALL_ARRAY = 9, - METACALL_MAP = 10, - METACALL_PTR = 11, - METACALL_FUTURE = 12, - METACALL_FUNCTION = 13, - METACALL_NULL = 14, - METACALL_CLASS = 15, - METACALL_OBJECT = 16, - METACALL_EXCEPTION = 17, - METACALL_THROWABLE = 18, - METACALL_SIZE = 19, - METACALL_INVALID = 20, -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from boolean @b\n\n @param[in] b\n Boolean will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_bool(b: ::std::os::raw::c_uchar) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from char @c\n\n @param[in] c\n Character will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_char(c: ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from short @s\n\n @param[in] s\n Short will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_short(s: ::std::os::raw::c_short) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from integer @i\n\n @param[in] i\n Integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_int(i: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from long @l\n\n @param[in] l\n Long integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_long(l: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from single precision floating point number @f\n\n @param[in] f\n Float will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_float(f: f32) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from double precision floating point number @d\n\n @param[in] d\n Double will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_double(d: f64) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from a C string @str\n\n @param[in] str\n Constant string will be copied into value (needs to be null terminated)\n\n @param[in] length\n Length of the constant string\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_string( - str_: *const ::std::os::raw::c_char, - length: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value buffer from array @buffer\n\n @param[in] buffer\n Constant memory block will be copied into value array\n\n @param[in] size\n Size in bytes of data contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_buffer( - buffer: *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value array from array of values @values\n\n @param[in] values\n Constant array of values will be copied into value list\n\n @param[in] size\n Number of elements contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_array( - values: *mut *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value map from array of tuples @map\n\n @param[in] tuples\n Constant array of tuples will be copied into value map\n\n @param[in] size\n Number of elements contained in the map\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_map( - tuples: *mut *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from pointer @ptr\n\n @param[in] ptr\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_ptr( - ptr: *const ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from future @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_future( - f: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from function @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_function( - f: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from function @f binding a closure @c to it\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @param[in] c\n Pointer to closure that will be binded into function @f\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_function_closure( - f: *mut ::std::os::raw::c_void, - c: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value of type null\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_null() -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from class @c\n\n @param[in] c\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_class( - c: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from object @o\n\n @param[in] o\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_object( - o: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from exception @ex\n\n @param[in] ex\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_exception( - ex: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a value from throwable @th\n\n @param[in] th\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] - pub fn metacall_value_create_throwable( - th: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Returns the size of the value\n\n @param[in] v\n Reference to the value\n\n @return\n Size in bytes of the value"] - pub fn metacall_value_size(v: *mut ::std::os::raw::c_void) -> usize; -} -unsafe extern "C" { - #[doc = " @brief\n Returns the amount of values this value contains\n\n @param[in] v\n Reference to the value\n\n @return\n Number of values @v represents"] - pub fn metacall_value_count(v: *mut ::std::os::raw::c_void) -> usize; -} -unsafe extern "C" { - #[doc = " @brief\n Provide type id of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return type id assigned to value"] - pub fn metacall_value_id(v: *mut ::std::os::raw::c_void) -> metacall_value_id; -} -unsafe extern "C" { - #[doc = " @brief\n Provide type id in a readable form (as string) of a type id\n\n @param[in] id\n Value type identifier\n\n @return\n Return string related to the type id"] - pub fn metacall_value_id_name(id: metacall_value_id) -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Provide type id in a readable form (as string) of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return string related to the type id assigned to value"] - pub fn metacall_value_type_name( - v: *mut ::std::os::raw::c_void, - ) -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Deep copies the value @v, the result copy resets\n the reference counter and ownership, including the finalizer\n\n @param[in] v\n Reference to the value to be copied\n\n @return\n Copy of the value @v on success, null otherwhise"] - pub fn metacall_value_copy(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Creates a new pointer value, with a reference to the\n data contained inside the value @v. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n\n In this case, void *ptr is a value equivalent to int*,\n and it points directly to the integer contained in void *v.\n Note that if we destroy the value @v, the reference will\n point to already freed memory, causing use-after-free when used.\n\n @param[in] v\n Reference to the value to be referenced\n\n @return\n A new value of type pointer, pointing to the @v data"] - pub fn metacall_value_reference(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n If you pass a reference previously created (i.e a value of\n type pointer, pointing to another value), it returns the\n original value. It does not modify the memory of the values\n neither allocates anything. If the value @v is pointing to\n has been deleted, it will cause an use-after-free. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n void *w = metacall_value_dereference(ptr);\n assert(v == w); // Both are the same value\n\n @param[in] v\n Reference to the value to be dereferenced\n\n @return\n The value containing the data which ptr is pointing to"] - pub fn metacall_value_dereference( - v: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Copies the ownership from @src to @dst, including the finalizer,\n and resets the owner and finalizer of @src\n\n @param[in] src\n Source value which will lose the ownership\n\n @param[in] dst\n Destination value which will recieve the ownership"] - pub fn metacall_value_move(src: *mut ::std::os::raw::c_void, dest: *mut ::std::os::raw::c_void); -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to boolean\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to boolean"] - pub fn metacall_value_to_bool(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_uchar; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to char\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to char"] - pub fn metacall_value_to_char(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to short\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to short"] - pub fn metacall_value_to_short(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_short; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to integer"] - pub fn metacall_value_to_int(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to long integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to long integer"] - pub fn metacall_value_to_long(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to single precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to float"] - pub fn metacall_value_to_float(v: *mut ::std::os::raw::c_void) -> f32; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to double precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to dobule"] - pub fn metacall_value_to_double(v: *mut ::std::os::raw::c_void) -> f64; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to string\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to C string (null terminated)"] - pub fn metacall_value_to_string(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to buffer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to memory block"] - pub fn metacall_value_to_buffer(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to array of values\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to array of values"] - pub fn metacall_value_to_array( - v: *mut ::std::os::raw::c_void, - ) -> *mut *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to map\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to map (array of tuples (array of values))"] - pub fn metacall_value_to_map( - v: *mut ::std::os::raw::c_void, - ) -> *mut *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to pointer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to pointer"] - pub fn metacall_value_to_ptr(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to future\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to future"] - pub fn metacall_value_to_future(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to function\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to function"] - pub fn metacall_value_to_function( - v: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to null\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to null"] - pub fn metacall_value_to_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to class\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to class"] - pub fn metacall_value_to_class(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to object\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to object"] - pub fn metacall_value_to_object(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to exception\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to exception"] - pub fn metacall_value_to_exception( - v: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v to throwable\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to throwable"] - pub fn metacall_value_to_throwable( - v: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign boolean @b to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] b\n Boolean to be assigned to value @v\n\n @return\n Value with boolean @b assigned to it"] - pub fn metacall_value_from_bool( - v: *mut ::std::os::raw::c_void, - b: ::std::os::raw::c_uchar, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign character @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Character to be assigned to value @v\n\n @return\n Value with char @c assigned to it"] - pub fn metacall_value_from_char( - v: *mut ::std::os::raw::c_void, - c: ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign short @s to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] s\n Short to be assigned to value @v\n\n @return\n Value with short @s assigned to it"] - pub fn metacall_value_from_short( - v: *mut ::std::os::raw::c_void, - s: ::std::os::raw::c_short, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign integer @i to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] i\n Integer to be assigned to value @v\n\n @return\n Value with integer @i assigned to it"] - pub fn metacall_value_from_int( - v: *mut ::std::os::raw::c_void, - i: ::std::os::raw::c_int, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign long integer @l to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] l\n Long integer to be assigned to value @v\n\n @return\n Value with long @l assigned to it"] - pub fn metacall_value_from_long( - v: *mut ::std::os::raw::c_void, - l: ::std::os::raw::c_long, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign single precision floating point @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Float to be assigned to value @v\n\n @return\n Value with float @f assigned to it"] - pub fn metacall_value_from_float( - v: *mut ::std::os::raw::c_void, - f: f32, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign double precision floating point @d to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] d\n Double to be assigned to value @v\n\n @return\n Value with double @d assigned to it"] - pub fn metacall_value_from_double( - v: *mut ::std::os::raw::c_void, - d: f64, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign string @str to value @v, truncates to @v size if it is smaller\n than @length + 1. It does not add null terminator if truncated.\n\n @param[in] v\n Reference to the value\n\n @param[in] str\n Constant string to be assigned to value @v (it needs to be null terminated)\n\n @param[in] length\n Length of the constant string @str\n\n @return\n Value with string @str assigned to it"] - pub fn metacall_value_from_string( - v: *mut ::std::os::raw::c_void, - str_: *const ::std::os::raw::c_char, - length: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign array @buffer to value buffer @v\n\n @param[in] v\n Reference to the value\n\n @param[in] buffer\n Constant array to be assigned to value @v\n\n @param[in] size\n Number of elements contained in @buffer\n\n @return\n Value with array @buffer assigned to it"] - pub fn metacall_value_from_buffer( - v: *mut ::std::os::raw::c_void, - buffer: *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign array of values @values to value array @v\n\n @param[in] v\n Reference to the value\n\n @param[in] values\n Constant array of values to be assigned to value array @v\n\n @param[in] size\n Number of values contained in constant array @values\n\n @return\n Value with array of values @values assigned to it"] - pub fn metacall_value_from_array( - v: *mut ::std::os::raw::c_void, - values: *mut *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign array of values @values to value map @v\n\n @param[in] v\n Reference to the value\n\n @param[in] tuples\n Constant array of tuples to be assigned to value map @v\n\n @param[in] size\n Number of values contained in constant array @tuples\n\n @return\n Value with array of tuples @tuples assigned to it"] - pub fn metacall_value_from_map( - v: *mut ::std::os::raw::c_void, - tuples: *mut *const ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign pointer reference @ptr to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ptr\n Pointer to be assigned to value @v\n\n @return\n Value with pointer @ptr assigned to it"] - pub fn metacall_value_from_ptr( - v: *mut ::std::os::raw::c_void, - ptr: *const ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign future @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Future to be assigned to value @v\n\n @return\n Value with future @f assigned to it"] - pub fn metacall_value_from_future( - v: *mut ::std::os::raw::c_void, - f: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign function @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Function to be assigned to value @v\n\n @return\n Value with function @f assigned to it"] - pub fn metacall_value_from_function( - v: *mut ::std::os::raw::c_void, - f: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign null to value @v\n\n @param[in] v\n Reference to the value\n\n @return\n Value with null assigned to it"] - pub fn metacall_value_from_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign class @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Class to be assigned to value @v\n\n @return\n Value with class @c assigned to it"] - pub fn metacall_value_from_class( - v: *mut ::std::os::raw::c_void, - c: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign object @o to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] o\n Object to be assigned to value @v\n\n @return\n Value with object @o assigned to it"] - pub fn metacall_value_from_object( - v: *mut ::std::os::raw::c_void, - o: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign exception @ex to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ex\n Exception to be assigned to value @v\n\n @return\n Value with exception @ex assigned to it"] - pub fn metacall_value_from_exception( - v: *mut ::std::os::raw::c_void, - ex: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Assign throwable @th to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] th\n Throwable to be assigned to value @v\n\n @return\n Value with throwable @th assigned to it"] - pub fn metacall_value_from_throwable( - v: *mut ::std::os::raw::c_void, - th: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Casts a value to a new type @id\n\n @param[in] v\n Reference to the value\n\n @param[in] id\n New type id of value to be casted\n\n @return\n Casted value or reference to @v if casting is between equivalent types"] - pub fn metacall_value_cast( - v: *mut ::std::os::raw::c_void, - id: metacall_value_id, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to boolean\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to boolean"] - pub fn metacall_value_cast_bool(v: *mut *mut ::std::os::raw::c_void) - -> ::std::os::raw::c_uchar; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to char\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to char"] - pub fn metacall_value_cast_char(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to short\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to short"] - pub fn metacall_value_cast_short( - v: *mut *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_short; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to int\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to int"] - pub fn metacall_value_cast_int(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to long\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to long"] - pub fn metacall_value_cast_long(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to float\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to float"] - pub fn metacall_value_cast_float(v: *mut *mut ::std::os::raw::c_void) -> f32; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to double\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to double"] - pub fn metacall_value_cast_double(v: *mut *mut ::std::os::raw::c_void) -> f64; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to string\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to a C string (null terminated)"] - pub fn metacall_value_cast_string( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to buffer\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to buffer"] - pub fn metacall_value_cast_buffer( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to array\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to array of values"] - pub fn metacall_value_cast_array( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to map\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to map"] - pub fn metacall_value_cast_map( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to ptr\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to ptr"] - pub fn metacall_value_cast_ptr( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to future\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to future"] - pub fn metacall_value_cast_future( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to function\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to function"] - pub fn metacall_value_cast_function( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to null\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to null"] - pub fn metacall_value_cast_null( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to class\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to class"] - pub fn metacall_value_cast_class( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to object\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to object"] - pub fn metacall_value_cast_object( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to exception\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to exception"] - pub fn metacall_value_cast_exception( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert value @v implicitly to throwable\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to throwable"] - pub fn metacall_value_cast_throwable( - v: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Destroy a value from scope stack\n\n @param[in] v\n Reference to the value"] - pub fn metacall_value_destroy(v: *mut ::std::os::raw::c_void); -} -pub type metacall_pid = pid_t; -pub type metacall_pre_fork_callback_ptr = ::std::option::Option< - unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, ->; -pub type metacall_post_fork_callback_ptr = ::std::option::Option< - unsafe extern "C" fn( - arg1: metacall_pid, - arg2: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int, ->; -unsafe extern "C" { - #[doc = " @brief\n Initialize fork detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_fork_initialize() -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Set fork hook callback\n\n @param[in] pre_callback\n Callback to be called before fork detour is executed\n\n @param[in] post_callback\n Callback to be called after fork detour is executed"] - pub fn metacall_fork( - pre_callback: metacall_pre_fork_callback_ptr, - post_callback: metacall_post_fork_callback_ptr, - ); -} -unsafe extern "C" { - #[doc = " @brief\n Unregister fork detours and destroy shared memory"] - pub fn metacall_fork_destroy(); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct metacall_initialize_configuration_type { - pub tag: *const ::std::os::raw::c_char, - pub options: *mut ::std::os::raw::c_void, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of metacall_initialize_configuration_type"] - [::std::mem::size_of::<metacall_initialize_configuration_type>() - 16usize]; - ["Alignment of metacall_initialize_configuration_type"] - [::std::mem::align_of::<metacall_initialize_configuration_type>() - 8usize]; - ["Offset of field: metacall_initialize_configuration_type::tag"] - [::std::mem::offset_of!(metacall_initialize_configuration_type, tag) - 0usize]; - ["Offset of field: metacall_initialize_configuration_type::options"] - [::std::mem::offset_of!(metacall_initialize_configuration_type, options) - 8usize]; -}; -pub type metacall_await_callback = ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, ->; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct metacall_await_callbacks_type { - pub resolve: metacall_await_callback, - pub reject: metacall_await_callback, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of metacall_await_callbacks_type"] - [::std::mem::size_of::<metacall_await_callbacks_type>() - 16usize]; - ["Alignment of metacall_await_callbacks_type"] - [::std::mem::align_of::<metacall_await_callbacks_type>() - 8usize]; - ["Offset of field: metacall_await_callbacks_type::resolve"] - [::std::mem::offset_of!(metacall_await_callbacks_type, resolve) - 0usize]; - ["Offset of field: metacall_await_callbacks_type::reject"] - [::std::mem::offset_of!(metacall_await_callbacks_type, reject) - 8usize]; -}; -pub type metacall_await_callbacks = metacall_await_callbacks_type; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct metacall_version_type { - pub major: ::std::os::raw::c_uint, - pub minor: ::std::os::raw::c_uint, - pub patch: ::std::os::raw::c_uint, - pub revision: *const ::std::os::raw::c_char, - pub str_: *const ::std::os::raw::c_char, - pub name: *const ::std::os::raw::c_char, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of metacall_version_type"][::std::mem::size_of::<metacall_version_type>() - 40usize]; - ["Alignment of metacall_version_type"] - [::std::mem::align_of::<metacall_version_type>() - 8usize]; - ["Offset of field: metacall_version_type::major"] - [::std::mem::offset_of!(metacall_version_type, major) - 0usize]; - ["Offset of field: metacall_version_type::minor"] - [::std::mem::offset_of!(metacall_version_type, minor) - 4usize]; - ["Offset of field: metacall_version_type::patch"] - [::std::mem::offset_of!(metacall_version_type, patch) - 8usize]; - ["Offset of field: metacall_version_type::revision"] - [::std::mem::offset_of!(metacall_version_type, revision) - 16usize]; - ["Offset of field: metacall_version_type::str_"] - [::std::mem::offset_of!(metacall_version_type, str_) - 24usize]; - ["Offset of field: metacall_version_type::name"] - [::std::mem::offset_of!(metacall_version_type, name) - 32usize]; -}; -unsafe extern "C" { - #[doc = " @brief\n Returns default serializer used by MetaCall\n\n @return\n Name of the serializer to be used with serialization methods"] - pub fn metacall_serial() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Returns default detour used by MetaCall\n\n @return\n Name of the detour to be used with detouring methods"] - pub fn metacall_detour() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Disables MetaCall logs, must be called before @metacall_initialize.\n\n When initializing MetaCall, it initializes a default logs to stdout\n if none was defined. If you want to benchmark or simply disable this\n default logs, you can call to this function before @metacall_initialize."] - pub fn metacall_log_null(); -} -unsafe extern "C" { - #[doc = " @brief\n Flags to be set in MetaCall library\n\n @param[in] flags\n Combination of flags referring to definitions METACALL_FLAGS_*"] - pub fn metacall_flags(flags: ::std::os::raw::c_int); -} -unsafe extern "C" { - #[doc = " @brief\n Initialize MetaCall library\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_initialize() -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Initialize MetaCall library with configuration arguments\n\n @param[in] initialize_config\n Extension of the script to be loaded in memory with data to be injected\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_initialize_ex( - initialize_config: *mut metacall_initialize_configuration_type, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Initialize MetaCall application arguments\n\n @param[in] argc\n Number of additional parameters to be passed to the runtime when initializing\n\n @param[in] argv\n Additional parameters to be passed to the runtime when initializing (when using MetaCall as an application)"] - pub fn metacall_initialize_args( - argc: ::std::os::raw::c_int, - argv: *mut *mut ::std::os::raw::c_char, - ); -} -unsafe extern "C" { - #[doc = " @brief\n Get the number of arguments in which MetaCall was initialized\n\n @return\n An integer equal or greater than zero"] - pub fn metacall_argc() -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the arguments in which MetaCall was initialized\n\n @return\n A pointer to an array of strings with the additional arguments"] - pub fn metacall_argv() -> *mut *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Check if script context is loaded by @tag\n\n @param[in] tag\n Extension of the script (if tag is NULL, it returns the status of the whole MetaCall instance)\n\n @return\n Zero if context is initialized, different from zero otherwise"] - pub fn metacall_is_initialized(tag: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Amount of function call arguments supported by MetaCall\n\n @return\n Number of arguments suported"] - pub fn metacall_args_size() -> usize; -} -unsafe extern "C" { - #[doc = " @brief\n Set a execution path defined by @path to the extension script @tag\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path to be loaded\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_execution_path( - tag: *const ::std::os::raw::c_char, - path: *const ::std::os::raw::c_char, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Set a execution path defined by @path to the extension script @tag with length\n\n @param[in] tag\n Extension of the script\n\n @param[in] tag_length\n Length of the extension of the tag\n\n @param[in] path\n Path to be loaded\n\n @param[in] path_length\n Length of the path\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_execution_path_s( - tag: *const ::std::os::raw::c_char, - tag_length: usize, - path: *const ::std::os::raw::c_char, - path_length: usize, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Loads a script from file specified by @path\n\n @param[in] tag\n Extension of the script\n\n @param[in] paths\n Path array of files\n\n @param[in] size\n Size of the array @paths\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_load_from_file( - tag: *const ::std::os::raw::c_char, - paths: *mut *const ::std::os::raw::c_char, - size: usize, - handle: *mut *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Loads a script from memory\n\n @param[in] tag\n Extension of the script\n\n @param[in] buffer\n Memory block representing the string of the script\n\n @param[in] size\n Memory block representing the string of the script\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_load_from_memory( - tag: *const ::std::os::raw::c_char, - buffer: *const ::std::os::raw::c_char, - size: usize, - handle: *mut *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Loads a package of scrips from file specified by @path into loader defined by @extension\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path of the package\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_load_from_package( - tag: *const ::std::os::raw::c_char, - path: *const ::std::os::raw::c_char, - handle: *mut *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Loads a a list of scrips from configuration specified by @path into loader\n with the following format:\n {\n \"language_id\": \"<tag>\",\n \"path\": \"<path>\",\n \"scripts\": [ \"<script0>\", \"<script1>\", ..., \"<scriptN>\" ]\n }\n\n @param[in] path\n Path of the configuration\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @param[in] allocator\n Pointer to allocator will allocate the configuration\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_load_from_configuration( - path: *const ::std::os::raw::c_char, - handle: *mut *mut ::std::os::raw::c_void, - allocator: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallv( - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallv_s( - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallhv( - handle: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n Includes @size in order to allow variadic arguments or safe calls\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallhv_s( - handle: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacall(name: *const ::std::os::raw::c_char, ...) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallt( - name: *const ::std::os::raw::c_char, - ids: *const metacall_value_id, - ... - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallt_s( - name: *const ::std::os::raw::c_char, - ids: *const metacall_value_id, - size: usize, - ... - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallht_s( - handle: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - ids: *const metacall_value_id, - size: usize, - ... - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get the function by @name\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] - pub fn metacall_function(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create an empty handler into a loader with name @name\n\n @param[in] loader\n Pointer to the loader which the handle belongs to\n\n @param[in] name\n Name of the handle\n\n @param[out] handle_ptr\n On success, returns the pointer to the handle created, otherwise NULL\n\n @return\n Return zero on success, different from zero on error"] - pub fn metacall_handle_initialize( - loader: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - handle_ptr: *mut *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Populate the objects of @handle_src into @handle_dest\n\n @param[inout] handle_dest\n Handle where the objects from @handle_src will be stored\n\n @param[in] handle_src\n Handle from where the objects will be copied\n\n @return\n Return zero on success, different from zero on error"] - pub fn metacall_handle_populate( - handle_dest: *mut ::std::os::raw::c_void, - handle_src: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the function by @name from @handle\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] - pub fn metacall_handle_function( - handle: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get the function parameter type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n @param[in] parameter\n The index of the parameter to be retrieved\n\n @param[out] id\n The parameter type id that will be returned\n\n @return\n Return 0 if the @parameter index exists and @func is valid, 1 otherwhise"] - pub fn metacall_function_parameter_type( - func: *mut ::std::os::raw::c_void, - parameter: usize, - id: *mut metacall_value_id, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the function return type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n\n @param[out] id\n The value id of the return type of the function @func\n\n @return\n Return 0 if the @func is valid, 1 otherwhise"] - pub fn metacall_function_return_type( - func: *mut ::std::os::raw::c_void, - id: *mut metacall_value_id, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get minimun mumber of arguments accepted by function @func\n\n @param[in] func\n Function reference\n\n @return\n Return mumber of arguments"] - pub fn metacall_function_size(func: *mut ::std::os::raw::c_void) -> usize; -} -unsafe extern "C" { - #[doc = " @brief\n Check if the function @func is asynchronous or synchronous\n\n @param[in] func\n Function reference\n\n @return\n Return 0 if it is syncrhonous, 1 if it is asynchronous and -1 if the function is NULL"] - pub fn metacall_function_async(func: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the handle by @name\n\n @param[in] tag\n Extension of the script\n\n @param[in] name\n Name of the handle\n\n @return\n Handle reference, null if the function does not exist"] - pub fn metacall_handle( - tag: *const ::std::os::raw::c_char, - name: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get name of a @handle\n\n @param[in] handle\n Pointer to the handle to be retrieved\n\n @return\n String that references the handle"] - pub fn metacall_handle_id(handle: *mut ::std::os::raw::c_void) - -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Return a value representing the handle as a map of functions (or values)\n\n @param[in] handle\n Reference to the handle to be described\n\n @return\n A value of type map on success, null otherwise"] - pub fn metacall_handle_export( - handle: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallfv( - func: *mut ::std::os::raw::c_void, - args: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of function arguments\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallfv_s( - func: *mut ::std::os::raw::c_void, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by variable arguments @va_args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallf(func: *mut ::std::os::raw::c_void, ...) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallfs( - func: *mut ::std::os::raw::c_void, - buffer: *const ::std::os::raw::c_char, - size: usize, - allocator: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallfmv( - func: *mut ::std::os::raw::c_void, - keys: *mut *mut ::std::os::raw::c_void, - values: *mut *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallfms( - func: *mut ::std::os::raw::c_void, - buffer: *const ::std::os::raw::c_char, - size: usize, - allocator: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Register a function by name @name and arguments @va_args\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] va_args\n Varidic function parameter types\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacall_register( - name: *const ::std::os::raw::c_char, - invoke: ::std::option::Option< - unsafe extern "C" fn( - arg1: usize, - arg2: *mut *mut ::std::os::raw::c_void, - arg3: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - func: *mut *mut ::std::os::raw::c_void, - return_type: metacall_value_id, - size: usize, - ... - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacall_registerv( - name: *const ::std::os::raw::c_char, - invoke: ::std::option::Option< - unsafe extern "C" fn( - arg1: usize, - arg2: *mut *mut ::std::os::raw::c_void, - arg3: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - func: *mut *mut ::std::os::raw::c_void, - return_type: metacall_value_id, - size: usize, - types: *mut metacall_value_id, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Obtain the loader instance by @tag\n\n @param[in] tag\n Tag in which the loader is identified, normally it is the extension of the script\n\n @return\n Pointer the loader by @tag"] - pub fn metacall_loader(tag: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] loader\n Opaque pointer to the loader in which you want to register the function (this allows to register the function into a different loader than the host)\n\n @param[in] handle\n Opaque pointer to the handle in which you want to register the function (if it is NULL, it will be defined on the global scope of the loader)\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Zero if the function was registered properly, distinct from zero otherwise"] - pub fn metacall_register_loaderv( - loader: *mut ::std::os::raw::c_void, - handle: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - invoke: ::std::option::Option< - unsafe extern "C" fn( - arg1: usize, - arg2: *mut *mut ::std::os::raw::c_void, - arg3: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - return_type: metacall_value_id, - size: usize, - types: *mut metacall_value_id, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacall_await( - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Awaits for a promise and registers a callback to be executed when a future is resolved\n\n @param[in] f\n The pointer to the future\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacall_await_future( - f: *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacall_await_s( - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfv_await( - func: *mut ::std::os::raw::c_void, - args: *mut *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfv_await_s( - func: *mut ::std::os::raw::c_void, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func (offered without function pointers for languages without support to function pointers)\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] cb\n Pointer to struct containing the function pointers to reject and resolve that will be executed when task completion or error\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfv_await_struct_s( - func: *mut ::std::os::raw::c_void, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - cb: metacall_await_callbacks, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] size\n Number of elements of the arrays @keys and @values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfmv_await( - func: *mut ::std::os::raw::c_void, - keys: *mut *mut ::std::os::raw::c_void, - values: *mut *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfmv_await_s( - func: *mut ::std::os::raw::c_void, - keys: *mut *mut ::std::os::raw::c_void, - values: *mut *mut ::std::os::raw::c_void, - size: usize, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfs_await( - func: *mut ::std::os::raw::c_void, - buffer: *const ::std::os::raw::c_char, - size: usize, - allocator: *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] - pub fn metacallfms_await( - func: *mut ::std::os::raw::c_void, - buffer: *const ::std::os::raw::c_char, - size: usize, - allocator: *mut ::std::os::raw::c_void, - resolve_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - reject_callback: ::std::option::Option< - unsafe extern "C" fn( - arg1: *mut ::std::os::raw::c_void, - arg2: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void, - >, - data: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get the class by @name\n\n @param[in] name\n Name of the class\n\n @return\n Class reference, null if the class does not exist"] - pub fn metacall_class(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a class method anonymously by value array @args (this procedure assumes there's no overloaded methods and does type conversion on values)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallv_class( - cls: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a class method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallt_class( - cls: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - ret: metacall_value_id, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Create a new object instance from @cls by value array @args\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the new object\n\n @param[in] args\n Array of pointers constructor parameters\n\n @param[in] size\n Number of elements of constructor parameters\n\n @return\n Pointer to the new object value instance"] - pub fn metacall_class_new( - cls: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get an attribute from @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the class attribute value or NULL if an error occurred"] - pub fn metacall_class_static_get( - cls: *mut ::std::os::raw::c_void, - key: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Set an attribute to @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] - pub fn metacall_class_static_set( - cls: *mut ::std::os::raw::c_void, - key: *const ::std::os::raw::c_char, - v: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Call an object method anonymously by value array @args\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallv_object( - obj: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Call a object method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] - pub fn metacallt_object( - obj: *mut ::std::os::raw::c_void, - name: *const ::std::os::raw::c_char, - ret: metacall_value_id, - args: *mut *mut ::std::os::raw::c_void, - size: usize, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get an attribute from @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the object attribute value or NULL if an error occurred"] - pub fn metacall_object_get( - obj: *mut ::std::os::raw::c_void, - key: *const ::std::os::raw::c_char, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Set an attribute to @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] - pub fn metacall_object_set( - obj: *mut ::std::os::raw::c_void, - key: *const ::std::os::raw::c_char, - v: *mut ::std::os::raw::c_void, - ) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the value contained by throwable object @th\n\n @param[in] th\n Pointer to the throwable object\n\n @return\n Pointer to the value inside of the throwable or NULL in case of error"] - pub fn metacall_throwable_value(th: *mut ::std::os::raw::c_void) - -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Provide information about all loaded objects\n\n @param[out] size\n Size in bytes of return buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n String containing introspection information"] - pub fn metacall_inspect( - size: *mut usize, - allocator: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Provide information about all loaded objects as a value\n\n @return\n Value containing introspection information"] - pub fn metacall_inspect_value() -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Convert the value @v to serialized string\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] v\n Reference to the value\n\n @param[out] size\n Size of new allocated string\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n New allocated string containing stringified value"] - pub fn metacall_serialize( - name: *const ::std::os::raw::c_char, - v: *mut ::std::os::raw::c_void, - size: *mut usize, - allocator: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Convert the string @buffer to value\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] buffer\n String to be deserialized\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n New allocated value representing the string (must be freed)"] - pub fn metacall_deserialize( - name: *const ::std::os::raw::c_char, - buffer: *const ::std::os::raw::c_char, - size: usize, - allocator: *mut ::std::os::raw::c_void, - ) -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Clear handle from memory and unload related resources\n\n @param[in] handle\n Reference to the handle to be unloaded\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_clear(handle: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; -} -unsafe extern "C" { - #[doc = " @brief\n Get the plugin extension handle to be used for loading plugins\n\n @return\n Pointer to the extension handle, or null if it failed to load"] - pub fn metacall_plugin_extension() -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get the handle containing all the functionality of the plugins from core\n\n @return\n Pointer to the core plugin handle, or null if it failed to load"] - pub fn metacall_plugin_core() -> *mut ::std::os::raw::c_void; -} -unsafe extern "C" { - #[doc = " @brief\n Get the plugin extension path to be used for accessing the plugins folder\n\n @return\n String containing the core plugin path, or null if it failed to load the plugin extension"] - pub fn metacall_plugin_path() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Destroy MetaCall library"] - pub fn metacall_destroy(); -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version struct\n\n @return\n Static struct containing unpacked version"] - pub fn metacall_version() -> *const metacall_version_type; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is @major,\n I is @minor and P is @patch\n\n @param[in] major\n Unsigned integer representing major version\n\n @param[in] minor\n Unsigned integer representing minor version\n\n @param[in] patch\n Unsigned integer representing patch version\n\n @return\n Hexadecimal integer containing packed version"] - pub fn metacall_version_hex_make( - major: ::std::os::raw::c_uint, - minor: ::std::os::raw::c_uint, - patch: ::std::os::raw::c_uint, - ) -> u32; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is major,\n I is minor and P is patch\n\n @return\n Hexadecimal integer containing packed version"] - pub fn metacall_version_hex() -> u32; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version string\n\n @return\n Static string containing module version"] - pub fn metacall_version_str() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version revision string\n\n @return\n Static string containing module version revision"] - pub fn metacall_version_revision() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module version name\n\n @return\n Static string containing module version name"] - pub fn metacall_version_name() -> *const ::std::os::raw::c_char; -} -unsafe extern "C" { - #[doc = " @brief\n Provide the module information\n\n @return\n Static string containing module information"] - pub fn metacall_print_info() -> *const ::std::os::raw::c_char; -} +pub type __pid_t = :: std :: os :: raw :: c_int ; pub type pid_t = __pid_t ; # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_allocator_id { METACALL_ALLOCATOR_STD = 0 , METACALL_ALLOCATOR_NGINX = 1 , } unsafe extern "C" { # [doc = " @brief\n Create an allocator instance\n\n @param[in] allocator_id\n Type of allocator to be created\n\n @param[in] ctx\n Context of the allocator\n\n @return\n Pointer to allocator if success, null otherwise"] pub fn metacall_allocator_create (allocator_id : metacall_allocator_id , ctx : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Reserve memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] size\n Size in bytes to be allocated\n\n @return\n Pointer to allocated data on success, null otherwise"] pub fn metacall_allocator_alloc (allocator : * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Reallocate memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Original pointer to data\n\n @param[in] size\n Original size in bytes\n\n @param[in] new_size\n New size in bytes to be reallocated\n\n @return\n Pointer to new reallocated data on success, null otherwise"] pub fn metacall_allocator_realloc (allocator : * mut :: std :: os :: raw :: c_void , data : * mut :: std :: os :: raw :: c_void , size : usize , new_size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Free memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Pointer to data to be freed"] pub fn metacall_allocator_free (allocator : * mut :: std :: os :: raw :: c_void , data : * mut :: std :: os :: raw :: c_void) ; } unsafe extern "C" { # [doc = " @brief\n Destroy an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance"] pub fn metacall_allocator_destroy (allocator : * mut :: std :: os :: raw :: c_void) ; } # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_exception_type { pub message : * const :: std :: os :: raw :: c_char , pub label : * const :: std :: os :: raw :: c_char , pub code : i64 , pub stacktrace : * const :: std :: os :: raw :: c_char , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_exception_type"] [:: std :: mem :: size_of :: < metacall_exception_type > () - 32usize] ; ["Alignment of metacall_exception_type"] [:: std :: mem :: align_of :: < metacall_exception_type > () - 8usize] ; ["Offset of field: metacall_exception_type::message"] [:: std :: mem :: offset_of ! (metacall_exception_type , message) - 0usize] ; ["Offset of field: metacall_exception_type::label"] [:: std :: mem :: offset_of ! (metacall_exception_type , label) - 8usize] ; ["Offset of field: metacall_exception_type::code"] [:: std :: mem :: offset_of ! (metacall_exception_type , code) - 16usize] ; ["Offset of field: metacall_exception_type::stacktrace"] [:: std :: mem :: offset_of ! (metacall_exception_type , stacktrace) - 24usize] ; } ; pub type metacall_exception = * mut metacall_exception_type ; unsafe extern "C" { # [doc = " @brief\n Create an throwable value from an exception with a simple API in a single instruction\n\n @param[in] label\n Label of the exception\n\n @param[in] code\n Error code of the exception\n\n @param[in] stacktrace\n Stack trace of the exception\n\n @param[in] message\n Message of the exception to be formatted with the variable arguments\n\n @param[in] va_args\n Arguments for formatting the message\n\n @return\n The value of type throwable containing the exception created"] pub fn metacall_error_throw (label : * const :: std :: os :: raw :: c_char , code : i64 , stacktrace : * const :: std :: os :: raw :: c_char , message : * const :: std :: os :: raw :: c_char , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Retrieve the exception from a value, it can be either a throwable value with an exception inside or an exception itself\n\n @param[in] v\n Value that represents the exception to be retrieved\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to @v\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_error_from_value (v : * mut :: std :: os :: raw :: c_void , ex : metacall_exception) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Retrieve last error that has happened after a call to any API from MetaCall\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to the internal MetaCall exception\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_error_last (ex : metacall_exception) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Clear last error that has happened after a call to any API from MetaCall"] pub fn metacall_error_clear () ; } unsafe extern "C" { # [doc = " @brief\n Initialize link detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_register (tag : * const :: std :: os :: raw :: c_char , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char , fn_ : :: std :: option :: Option < unsafe extern "C" fn () >) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] loader\n Pointer to the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_register_loader (loader : * mut :: std :: os :: raw :: c_void , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char , fn_ : :: std :: option :: Option < unsafe extern "C" fn () >) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Remove the hook previously registered\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_unregister (tag : * const :: std :: os :: raw :: c_char , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Unregister link detours and destroy shared memory"] pub fn metacall_link_destroy () ; } # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_log_id { METACALL_LOG_STDIO = 0 , METACALL_LOG_FILE = 1 , METACALL_LOG_SOCKET = 2 , METACALL_LOG_SYSLOG = 3 , METACALL_LOG_NGINX = 4 , METACALL_LOG_CUSTOM = 5 , } unsafe extern "C" { # [doc = " @brief\n Create a log instance\n\n @param[in] log_id\n Type of log to be created\n\n @param[in] ctx\n Context of the log (a pointer to metacall_log_{stdio, file, socket, syslog, nginx, custom}_type)\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_log (log_id : metacall_log_id , ctx : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_value_id { METACALL_BOOL = 0 , METACALL_CHAR = 1 , METACALL_SHORT = 2 , METACALL_INT = 3 , METACALL_LONG = 4 , METACALL_FLOAT = 5 , METACALL_DOUBLE = 6 , METACALL_STRING = 7 , METACALL_BUFFER = 8 , METACALL_ARRAY = 9 , METACALL_MAP = 10 , METACALL_PTR = 11 , METACALL_FUTURE = 12 , METACALL_FUNCTION = 13 , METACALL_NULL = 14 , METACALL_CLASS = 15 , METACALL_OBJECT = 16 , METACALL_EXCEPTION = 17 , METACALL_THROWABLE = 18 , METACALL_SIZE = 19 , METACALL_INVALID = 20 , } unsafe extern "C" { # [doc = " @brief\n Create a value from boolean @b\n\n @param[in] b\n Boolean will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_bool (b : :: std :: os :: raw :: c_uchar) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from char @c\n\n @param[in] c\n Character will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_char (c : :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from short @s\n\n @param[in] s\n Short will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_short (s : :: std :: os :: raw :: c_short) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from integer @i\n\n @param[in] i\n Integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_int (i : :: std :: os :: raw :: c_int) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from long @l\n\n @param[in] l\n Long integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_long (l : :: std :: os :: raw :: c_long) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from single precision floating point number @f\n\n @param[in] f\n Float will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_float (f : f32) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from double precision floating point number @d\n\n @param[in] d\n Double will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_double (d : f64) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from a C string @str\n\n @param[in] str\n Constant string will be copied into value (needs to be null terminated)\n\n @param[in] length\n Length of the constant string\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_string (str_ : * const :: std :: os :: raw :: c_char , length : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value buffer from array @buffer\n\n @param[in] buffer\n Constant memory block will be copied into value array\n\n @param[in] size\n Size in bytes of data contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_buffer (buffer : * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value array from array of values @values\n\n @param[in] values\n Constant array of values will be copied into value list\n\n @param[in] size\n Number of elements contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_array (values : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value map from array of tuples @map\n\n @param[in] tuples\n Constant array of tuples will be copied into value map\n\n @param[in] size\n Number of elements contained in the map\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_map (tuples : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from pointer @ptr\n\n @param[in] ptr\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_ptr (ptr : * const :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from future @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_future (f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from function @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_function (f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from function @f binding a closure @c to it\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @param[in] c\n Pointer to closure that will be binded into function @f\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_function_closure (f : * mut :: std :: os :: raw :: c_void , c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value of type null\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_null () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from class @c\n\n @param[in] c\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_class (c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from object @o\n\n @param[in] o\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_object (o : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from exception @ex\n\n @param[in] ex\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_exception (ex : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from throwable @th\n\n @param[in] th\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_throwable (th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Returns the size of the value\n\n @param[in] v\n Reference to the value\n\n @return\n Size in bytes of the value"] pub fn metacall_value_size (v : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Returns the amount of values this value contains\n\n @param[in] v\n Reference to the value\n\n @return\n Number of values @v represents"] pub fn metacall_value_count (v : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Provide type id of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return type id assigned to value"] pub fn metacall_value_id (v : * mut :: std :: os :: raw :: c_void) -> metacall_value_id ; } unsafe extern "C" { # [doc = " @brief\n Provide type id in a readable form (as string) of a type id\n\n @param[in] id\n Value type identifier\n\n @return\n Return string related to the type id"] pub fn metacall_value_id_name (id : metacall_value_id) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide type id in a readable form (as string) of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return string related to the type id assigned to value"] pub fn metacall_value_type_name (v : * mut :: std :: os :: raw :: c_void) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Deep copies the value @v, the result copy resets\n the reference counter and ownership, including the finalizer\n\n @param[in] v\n Reference to the value to be copied\n\n @return\n Copy of the value @v on success, null otherwhise"] pub fn metacall_value_copy (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Creates a new pointer value, with a reference to the\n data contained inside the value @v. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n\n In this case, void *ptr is a value equivalent to int*,\n and it points directly to the integer contained in void *v.\n Note that if we destroy the value @v, the reference will\n point to already freed memory, causing use-after-free when used.\n\n @param[in] v\n Reference to the value to be referenced\n\n @return\n A new value of type pointer, pointing to the @v data"] pub fn metacall_value_reference (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n If you pass a reference previously created (i.e a value of\n type pointer, pointing to another value), it returns the\n original value. It does not modify the memory of the values\n neither allocates anything. If the value @v is pointing to\n has been deleted, it will cause an use-after-free. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n void *w = metacall_value_dereference(ptr);\n assert(v == w); // Both are the same value\n\n @param[in] v\n Reference to the value to be dereferenced\n\n @return\n The value containing the data which ptr is pointing to"] pub fn metacall_value_dereference (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Copies the ownership from @src to @dst, including the finalizer,\n and resets the owner and finalizer of @src\n\n @param[in] src\n Source value which will lose the ownership\n\n @param[in] dst\n Destination value which will recieve the ownership"] pub fn metacall_value_move (src : * mut :: std :: os :: raw :: c_void , dest : * mut :: std :: os :: raw :: c_void) ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to boolean\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to boolean"] pub fn metacall_value_to_bool (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_uchar ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to char\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to char"] pub fn metacall_value_to_char (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to short\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to short"] pub fn metacall_value_to_short (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_short ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to integer"] pub fn metacall_value_to_int (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to long integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to long integer"] pub fn metacall_value_to_long (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_long ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to single precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to float"] pub fn metacall_value_to_float (v : * mut :: std :: os :: raw :: c_void) -> f32 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to double precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to dobule"] pub fn metacall_value_to_double (v : * mut :: std :: os :: raw :: c_void) -> f64 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to string\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to C string (null terminated)"] pub fn metacall_value_to_string (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to buffer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to memory block"] pub fn metacall_value_to_buffer (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to array of values\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to array of values"] pub fn metacall_value_to_array (v : * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to map\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to map (array of tuples (array of values))"] pub fn metacall_value_to_map (v : * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to pointer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to pointer"] pub fn metacall_value_to_ptr (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to future\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to future"] pub fn metacall_value_to_future (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to function\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to function"] pub fn metacall_value_to_function (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to null\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to null"] pub fn metacall_value_to_null (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to class\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to class"] pub fn metacall_value_to_class (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to object\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to object"] pub fn metacall_value_to_object (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to exception\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to exception"] pub fn metacall_value_to_exception (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to throwable\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to throwable"] pub fn metacall_value_to_throwable (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign boolean @b to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] b\n Boolean to be assigned to value @v\n\n @return\n Value with boolean @b assigned to it"] pub fn metacall_value_from_bool (v : * mut :: std :: os :: raw :: c_void , b : :: std :: os :: raw :: c_uchar) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign character @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Character to be assigned to value @v\n\n @return\n Value with char @c assigned to it"] pub fn metacall_value_from_char (v : * mut :: std :: os :: raw :: c_void , c : :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign short @s to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] s\n Short to be assigned to value @v\n\n @return\n Value with short @s assigned to it"] pub fn metacall_value_from_short (v : * mut :: std :: os :: raw :: c_void , s : :: std :: os :: raw :: c_short) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign integer @i to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] i\n Integer to be assigned to value @v\n\n @return\n Value with integer @i assigned to it"] pub fn metacall_value_from_int (v : * mut :: std :: os :: raw :: c_void , i : :: std :: os :: raw :: c_int) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign long integer @l to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] l\n Long integer to be assigned to value @v\n\n @return\n Value with long @l assigned to it"] pub fn metacall_value_from_long (v : * mut :: std :: os :: raw :: c_void , l : :: std :: os :: raw :: c_long) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign single precision floating point @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Float to be assigned to value @v\n\n @return\n Value with float @f assigned to it"] pub fn metacall_value_from_float (v : * mut :: std :: os :: raw :: c_void , f : f32) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign double precision floating point @d to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] d\n Double to be assigned to value @v\n\n @return\n Value with double @d assigned to it"] pub fn metacall_value_from_double (v : * mut :: std :: os :: raw :: c_void , d : f64) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign string @str to value @v, truncates to @v size if it is smaller\n than @length + 1. It does not add null terminator if truncated.\n\n @param[in] v\n Reference to the value\n\n @param[in] str\n Constant string to be assigned to value @v (it needs to be null terminated)\n\n @param[in] length\n Length of the constant string @str\n\n @return\n Value with string @str assigned to it"] pub fn metacall_value_from_string (v : * mut :: std :: os :: raw :: c_void , str_ : * const :: std :: os :: raw :: c_char , length : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array @buffer to value buffer @v\n\n @param[in] v\n Reference to the value\n\n @param[in] buffer\n Constant array to be assigned to value @v\n\n @param[in] size\n Number of elements contained in @buffer\n\n @return\n Value with array @buffer assigned to it"] pub fn metacall_value_from_buffer (v : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array of values @values to value array @v\n\n @param[in] v\n Reference to the value\n\n @param[in] values\n Constant array of values to be assigned to value array @v\n\n @param[in] size\n Number of values contained in constant array @values\n\n @return\n Value with array of values @values assigned to it"] pub fn metacall_value_from_array (v : * mut :: std :: os :: raw :: c_void , values : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array of values @values to value map @v\n\n @param[in] v\n Reference to the value\n\n @param[in] tuples\n Constant array of tuples to be assigned to value map @v\n\n @param[in] size\n Number of values contained in constant array @tuples\n\n @return\n Value with array of tuples @tuples assigned to it"] pub fn metacall_value_from_map (v : * mut :: std :: os :: raw :: c_void , tuples : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign pointer reference @ptr to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ptr\n Pointer to be assigned to value @v\n\n @return\n Value with pointer @ptr assigned to it"] pub fn metacall_value_from_ptr (v : * mut :: std :: os :: raw :: c_void , ptr : * const :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign future @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Future to be assigned to value @v\n\n @return\n Value with future @f assigned to it"] pub fn metacall_value_from_future (v : * mut :: std :: os :: raw :: c_void , f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign function @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Function to be assigned to value @v\n\n @return\n Value with function @f assigned to it"] pub fn metacall_value_from_function (v : * mut :: std :: os :: raw :: c_void , f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign null to value @v\n\n @param[in] v\n Reference to the value\n\n @return\n Value with null assigned to it"] pub fn metacall_value_from_null (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign class @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Class to be assigned to value @v\n\n @return\n Value with class @c assigned to it"] pub fn metacall_value_from_class (v : * mut :: std :: os :: raw :: c_void , c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign object @o to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] o\n Object to be assigned to value @v\n\n @return\n Value with object @o assigned to it"] pub fn metacall_value_from_object (v : * mut :: std :: os :: raw :: c_void , o : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign exception @ex to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ex\n Exception to be assigned to value @v\n\n @return\n Value with exception @ex assigned to it"] pub fn metacall_value_from_exception (v : * mut :: std :: os :: raw :: c_void , ex : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign throwable @th to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] th\n Throwable to be assigned to value @v\n\n @return\n Value with throwable @th assigned to it"] pub fn metacall_value_from_throwable (v : * mut :: std :: os :: raw :: c_void , th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Casts a value to a new type @id\n\n @param[in] v\n Reference to the value\n\n @param[in] id\n New type id of value to be casted\n\n @return\n Casted value or reference to @v if casting is between equivalent types"] pub fn metacall_value_cast (v : * mut :: std :: os :: raw :: c_void , id : metacall_value_id) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to boolean\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to boolean"] pub fn metacall_value_cast_bool (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_uchar ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to char\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to char"] pub fn metacall_value_cast_char (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to short\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to short"] pub fn metacall_value_cast_short (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_short ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to int\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to int"] pub fn metacall_value_cast_int (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to long\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to long"] pub fn metacall_value_cast_long (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_long ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to float\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to float"] pub fn metacall_value_cast_float (v : * mut * mut :: std :: os :: raw :: c_void) -> f32 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to double\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to double"] pub fn metacall_value_cast_double (v : * mut * mut :: std :: os :: raw :: c_void) -> f64 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to string\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to a C string (null terminated)"] pub fn metacall_value_cast_string (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to buffer\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to buffer"] pub fn metacall_value_cast_buffer (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to array\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to array of values"] pub fn metacall_value_cast_array (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to map\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to map"] pub fn metacall_value_cast_map (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to ptr\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to ptr"] pub fn metacall_value_cast_ptr (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to future\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to future"] pub fn metacall_value_cast_future (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to function\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to function"] pub fn metacall_value_cast_function (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to null\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to null"] pub fn metacall_value_cast_null (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to class\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to class"] pub fn metacall_value_cast_class (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to object\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to object"] pub fn metacall_value_cast_object (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to exception\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to exception"] pub fn metacall_value_cast_exception (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to throwable\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to throwable"] pub fn metacall_value_cast_throwable (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Destroy a value from scope stack\n\n @param[in] v\n Reference to the value"] pub fn metacall_value_destroy (v : * mut :: std :: os :: raw :: c_void) ; } pub type metacall_pid = pid_t ; pub type metacall_pre_fork_callback_ptr = :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int > ; pub type metacall_post_fork_callback_ptr = :: std :: option :: Option < unsafe extern "C" fn (arg1 : metacall_pid , arg2 : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int > ; unsafe extern "C" { # [doc = " @brief\n Initialize fork detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_fork_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Set fork hook callback\n\n @param[in] pre_callback\n Callback to be called before fork detour is executed\n\n @param[in] post_callback\n Callback to be called after fork detour is executed"] pub fn metacall_fork (pre_callback : metacall_pre_fork_callback_ptr , post_callback : metacall_post_fork_callback_ptr) ; } unsafe extern "C" { # [doc = " @brief\n Unregister fork detours and destroy shared memory"] pub fn metacall_fork_destroy () ; } # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_initialize_configuration_type { pub tag : * const :: std :: os :: raw :: c_char , pub options : * mut :: std :: os :: raw :: c_void , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_initialize_configuration_type"] [:: std :: mem :: size_of :: < metacall_initialize_configuration_type > () - 16usize] ; ["Alignment of metacall_initialize_configuration_type"] [:: std :: mem :: align_of :: < metacall_initialize_configuration_type > () - 8usize] ; ["Offset of field: metacall_initialize_configuration_type::tag"] [:: std :: mem :: offset_of ! (metacall_initialize_configuration_type , tag) - 0usize] ; ["Offset of field: metacall_initialize_configuration_type::options"] [:: std :: mem :: offset_of ! (metacall_initialize_configuration_type , options) - 8usize] ; } ; pub type metacall_await_callback = :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > ; # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_await_callbacks_type { pub resolve : metacall_await_callback , pub reject : metacall_await_callback , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_await_callbacks_type"] [:: std :: mem :: size_of :: < metacall_await_callbacks_type > () - 16usize] ; ["Alignment of metacall_await_callbacks_type"] [:: std :: mem :: align_of :: < metacall_await_callbacks_type > () - 8usize] ; ["Offset of field: metacall_await_callbacks_type::resolve"] [:: std :: mem :: offset_of ! (metacall_await_callbacks_type , resolve) - 0usize] ; ["Offset of field: metacall_await_callbacks_type::reject"] [:: std :: mem :: offset_of ! (metacall_await_callbacks_type , reject) - 8usize] ; } ; pub type metacall_await_callbacks = metacall_await_callbacks_type ; # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_version_type { pub major : :: std :: os :: raw :: c_uint , pub minor : :: std :: os :: raw :: c_uint , pub patch : :: std :: os :: raw :: c_uint , pub revision : * const :: std :: os :: raw :: c_char , pub str_ : * const :: std :: os :: raw :: c_char , pub name : * const :: std :: os :: raw :: c_char , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_version_type"] [:: std :: mem :: size_of :: < metacall_version_type > () - 40usize] ; ["Alignment of metacall_version_type"] [:: std :: mem :: align_of :: < metacall_version_type > () - 8usize] ; ["Offset of field: metacall_version_type::major"] [:: std :: mem :: offset_of ! (metacall_version_type , major) - 0usize] ; ["Offset of field: metacall_version_type::minor"] [:: std :: mem :: offset_of ! (metacall_version_type , minor) - 4usize] ; ["Offset of field: metacall_version_type::patch"] [:: std :: mem :: offset_of ! (metacall_version_type , patch) - 8usize] ; ["Offset of field: metacall_version_type::revision"] [:: std :: mem :: offset_of ! (metacall_version_type , revision) - 16usize] ; ["Offset of field: metacall_version_type::str_"] [:: std :: mem :: offset_of ! (metacall_version_type , str_) - 24usize] ; ["Offset of field: metacall_version_type::name"] [:: std :: mem :: offset_of ! (metacall_version_type , name) - 32usize] ; } ; unsafe extern "C" { # [doc = " @brief\n Returns default serializer used by MetaCall\n\n @return\n Name of the serializer to be used with serialization methods"] pub fn metacall_serial () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Returns default detour used by MetaCall\n\n @return\n Name of the detour to be used with detouring methods"] pub fn metacall_detour () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Disables MetaCall logs, must be called before @metacall_initialize.\n\n When initializing MetaCall, it initializes a default logs to stdout\n if none was defined. If you want to benchmark or simply disable this\n default logs, you can call to this function before @metacall_initialize."] pub fn metacall_log_null () ; } unsafe extern "C" { # [doc = " @brief\n Flags to be set in MetaCall library\n\n @param[in] flags\n Combination of flags referring to definitions METACALL_FLAGS_*"] pub fn metacall_flags (flags : :: std :: os :: raw :: c_int) ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall library\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall library with configuration arguments\n\n @param[in] initialize_config\n Extension of the script to be loaded in memory with data to be injected\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_initialize_ex (initialize_config : * mut metacall_initialize_configuration_type) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall application arguments\n\n @param[in] argc\n Number of additional parameters to be passed to the runtime when initializing\n\n @param[in] argv\n Additional parameters to be passed to the runtime when initializing (when using MetaCall as an application)"] pub fn metacall_initialize_args (argc : :: std :: os :: raw :: c_int , argv : * mut * mut :: std :: os :: raw :: c_char) ; } unsafe extern "C" { # [doc = " @brief\n Get the number of arguments in which MetaCall was initialized\n\n @return\n An integer equal or greater than zero"] pub fn metacall_argc () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the arguments in which MetaCall was initialized\n\n @return\n A pointer to an array of strings with the additional arguments"] pub fn metacall_argv () -> * mut * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Check if script context is loaded by @tag\n\n @param[in] tag\n Extension of the script (if tag is NULL, it returns the status of the whole MetaCall instance)\n\n @return\n Zero if context is initialized, different from zero otherwise"] pub fn metacall_is_initialized (tag : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Amount of function call arguments supported by MetaCall\n\n @return\n Number of arguments suported"] pub fn metacall_args_size () -> usize ; } unsafe extern "C" { # [doc = " @brief\n Set a execution path defined by @path to the extension script @tag\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path to be loaded\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_execution_path (tag : * const :: std :: os :: raw :: c_char , path : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Set a execution path defined by @path to the extension script @tag with length\n\n @param[in] tag\n Extension of the script\n\n @param[in] tag_length\n Length of the extension of the tag\n\n @param[in] path\n Path to be loaded\n\n @param[in] path_length\n Length of the path\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_execution_path_s (tag : * const :: std :: os :: raw :: c_char , tag_length : usize , path : * const :: std :: os :: raw :: c_char , path_length : usize) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a script from file specified by @path\n\n @param[in] tag\n Extension of the script\n\n @param[in] paths\n Path array of files\n\n @param[in] size\n Size of the array @paths\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_file (tag : * const :: std :: os :: raw :: c_char , paths : * mut * const :: std :: os :: raw :: c_char , size : usize , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a script from memory\n\n @param[in] tag\n Extension of the script\n\n @param[in] buffer\n Memory block representing the string of the script\n\n @param[in] size\n Memory block representing the string of the script\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_memory (tag : * const :: std :: os :: raw :: c_char , buffer : * const :: std :: os :: raw :: c_char , size : usize , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a package of scrips from file specified by @path into loader defined by @extension\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path of the package\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_package (tag : * const :: std :: os :: raw :: c_char , path : * const :: std :: os :: raw :: c_char , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a a list of scrips from configuration specified by @path into loader\n with the following format:\n {\n \"language_id\": \"<tag>\",\n \"path\": \"<path>\",\n \"scripts\": [ \"<script0>\", \"<script1>\", ..., \"<scriptN>\" ]\n }\n\n @param[in] path\n Path of the configuration\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @param[in] allocator\n Pointer to allocator will allocate the configuration\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_configuration (path : * const :: std :: os :: raw :: c_char , handle : * mut * mut :: std :: os :: raw :: c_void , allocator : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_s (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallhv (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n Includes @size in order to allow variadic arguments or safe calls\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallhv_s (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall (name : * const :: std :: os :: raw :: c_char , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt (name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_s (name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , size : usize , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallht_s (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , size : usize , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the function by @name\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] pub fn metacall_function (name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create an empty handler into a loader with name @name\n\n @param[in] loader\n Pointer to the loader which the handle belongs to\n\n @param[in] name\n Name of the handle\n\n @param[out] handle_ptr\n On success, returns the pointer to the handle created, otherwise NULL\n\n @return\n Return zero on success, different from zero on error"] pub fn metacall_handle_initialize (loader : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , handle_ptr : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Populate the objects of @handle_src into @handle_dest\n\n @param[inout] handle_dest\n Handle where the objects from @handle_src will be stored\n\n @param[in] handle_src\n Handle from where the objects will be copied\n\n @return\n Return zero on success, different from zero on error"] pub fn metacall_handle_populate (handle_dest : * mut :: std :: os :: raw :: c_void , handle_src : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the function by @name from @handle\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] pub fn metacall_handle_function (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the function parameter type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n @param[in] parameter\n The index of the parameter to be retrieved\n\n @param[out] id\n The parameter type id that will be returned\n\n @return\n Return 0 if the @parameter index exists and @func is valid, 1 otherwhise"] pub fn metacall_function_parameter_type (func : * mut :: std :: os :: raw :: c_void , parameter : usize , id : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the function return type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n\n @param[out] id\n The value id of the return type of the function @func\n\n @return\n Return 0 if the @func is valid, 1 otherwhise"] pub fn metacall_function_return_type (func : * mut :: std :: os :: raw :: c_void , id : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get minimun mumber of arguments accepted by function @func\n\n @param[in] func\n Function reference\n\n @return\n Return mumber of arguments"] pub fn metacall_function_size (func : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Check if the function @func is asynchronous or synchronous\n\n @param[in] func\n Function reference\n\n @return\n Return 0 if it is syncrhonous, 1 if it is asynchronous and -1 if the function is NULL"] pub fn metacall_function_async (func : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the handle by @name\n\n @param[in] tag\n Extension of the script\n\n @param[in] name\n Name of the handle\n\n @return\n Handle reference, null if the function does not exist"] pub fn metacall_handle (tag : * const :: std :: os :: raw :: c_char , name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get name of a @handle\n\n @param[in] handle\n Pointer to the handle to be retrieved\n\n @return\n String that references the handle"] pub fn metacall_handle_id (handle : * mut :: std :: os :: raw :: c_void) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Return a value representing the handle as a map of functions (or values)\n\n @param[in] handle\n Reference to the handle to be described\n\n @return\n A value of type map on success, null otherwise"] pub fn metacall_handle_export (handle : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfv (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of function arguments\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfv_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by variable arguments @va_args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallf (func : * mut :: std :: os :: raw :: c_void , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfs (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfmv (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfms (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @va_args\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] va_args\n Varidic function parameter types\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall_register (name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , func : * mut * mut :: std :: os :: raw :: c_void , return_type : metacall_value_id , size : usize , ...) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall_registerv (name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , func : * mut * mut :: std :: os :: raw :: c_void , return_type : metacall_value_id , size : usize , types : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Obtain the loader instance by @tag\n\n @param[in] tag\n Tag in which the loader is identified, normally it is the extension of the script\n\n @return\n Pointer the loader by @tag"] pub fn metacall_loader (tag : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] loader\n Opaque pointer to the loader in which you want to register the function (this allows to register the function into a different loader than the host)\n\n @param[in] handle\n Opaque pointer to the handle in which you want to register the function (if it is NULL, it will be defined on the global scope of the loader)\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Zero if the function was registered properly, distinct from zero otherwise"] pub fn metacall_register_loaderv (loader : * mut :: std :: os :: raw :: c_void , handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , return_type : metacall_value_id , size : usize , types : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Awaits for a promise and registers a callback to be executed when a future is resolved\n\n @param[in] f\n The pointer to the future\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await_future (f : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await_s (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func (offered without function pointers for languages without support to function pointers)\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] cb\n Pointer to struct containing the function pointers to reject and resolve that will be executed when task completion or error\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await_struct_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , cb : metacall_await_callbacks , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] size\n Number of elements of the arrays @keys and @values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfmv_await (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfmv_await_s (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfs_await (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfms_await (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the class by @name\n\n @param[in] name\n Name of the class\n\n @return\n Class reference, null if the class does not exist"] pub fn metacall_class (name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a class method anonymously by value array @args (this procedure assumes there's no overloaded methods and does type conversion on values)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_class (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a class method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_class (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ret : metacall_value_id , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a new object instance from @cls by value array @args\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the new object\n\n @param[in] args\n Array of pointers constructor parameters\n\n @param[in] size\n Number of elements of constructor parameters\n\n @return\n Pointer to the new object value instance"] pub fn metacall_class_new (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get an attribute from @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the class attribute value or NULL if an error occurred"] pub fn metacall_class_static_get (cls : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Set an attribute to @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] pub fn metacall_class_static_set (cls : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Call an object method anonymously by value array @args\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_object (obj : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a object method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_object (obj : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ret : metacall_value_id , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get an attribute from @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the object attribute value or NULL if an error occurred"] pub fn metacall_object_get (obj : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Set an attribute to @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] pub fn metacall_object_set (obj : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the value contained by throwable object @th\n\n @param[in] th\n Pointer to the throwable object\n\n @return\n Pointer to the value inside of the throwable or NULL in case of error"] pub fn metacall_throwable_value (th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Provide information about all loaded objects\n\n @param[out] size\n Size in bytes of return buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n String containing introspection information"] pub fn metacall_inspect (size : * mut usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide information about all loaded objects as a value\n\n @return\n Value containing introspection information"] pub fn metacall_inspect_value () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert the value @v to serialized string\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] v\n Reference to the value\n\n @param[out] size\n Size of new allocated string\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n New allocated string containing stringified value"] pub fn metacall_serialize (name : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void , size : * mut usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert the string @buffer to value\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] buffer\n String to be deserialized\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n New allocated value representing the string (must be freed)"] pub fn metacall_deserialize (name : * const :: std :: os :: raw :: c_char , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Clear handle from memory and unload related resources\n\n @param[in] handle\n Reference to the handle to be unloaded\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_clear (handle : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the plugin extension handle to be used for loading plugins\n\n @return\n Pointer to the extension handle, or null if it failed to load"] pub fn metacall_plugin_extension () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the handle containing all the functionality of the plugins from core\n\n @return\n Pointer to the core plugin handle, or null if it failed to load"] pub fn metacall_plugin_core () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the plugin extension path to be used for accessing the plugins folder\n\n @return\n String containing the core plugin path, or null if it failed to load the plugin extension"] pub fn metacall_plugin_path () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Destroy MetaCall library"] pub fn metacall_destroy () ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version struct\n\n @return\n Static struct containing unpacked version"] pub fn metacall_version () -> * const metacall_version_type ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is @major,\n I is @minor and P is @patch\n\n @param[in] major\n Unsigned integer representing major version\n\n @param[in] minor\n Unsigned integer representing minor version\n\n @param[in] patch\n Unsigned integer representing patch version\n\n @return\n Hexadecimal integer containing packed version"] pub fn metacall_version_hex_make (major : :: std :: os :: raw :: c_uint , minor : :: std :: os :: raw :: c_uint , patch : :: std :: os :: raw :: c_uint) -> u32 ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is major,\n I is minor and P is patch\n\n @return\n Hexadecimal integer containing packed version"] pub fn metacall_version_hex () -> u32 ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version string\n\n @return\n Static string containing module version"] pub fn metacall_version_str () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version revision string\n\n @return\n Static string containing module version revision"] pub fn metacall_version_revision () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version name\n\n @return\n Static string containing module version name"] pub fn metacall_version_name () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module information\n\n @return\n Static string containing module information"] pub fn metacall_print_info () -> * const :: std :: os :: raw :: c_char ; } \ No newline at end of file From 020dc0e1512729a08512c9ce2afe0c0bd2cc6fb5 Mon Sep 17 00:00:00 2001 From: Fahd Ashour <fahd.fady212@gmail.com> Date: Thu, 4 Sep 2025 18:04:05 +0300 Subject: [PATCH 074/109] fix and refactor: rust port not finding metacall shared libraries and config files (#569) * refactor(rs_port): init translating search functionality * stash * CI: update rust workflow for testing Signed-off-by: fahdfady <fahd.fady212@gmail.com> * CI(release-rust): update test job to use matrix strategy for OS compatibility Signed-off-by: fahdfady <fahd.fady212@gmail.com> * CI: rust release, remove windows * canonicalize * Update build.rs * Update release-rust.yml * Update release-rust.yml * Update release-rust.yml --------- Signed-off-by: fahdfady <fahd.fady212@gmail.com> Co-authored-by: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> --- .github/workflows/release-rust.yml | 35 +++++- source/ports/rs_port/build.rs | 168 +++++++++++++++++++++++++++-- 2 files changed, 191 insertions(+), 12 deletions(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 10baaf1e7..13644cd0f 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -1,11 +1,12 @@ name: Release Rust Crates on: + workflow_dispatch: + pull_request: push: branches: [ master, develop ] paths: - - 'source/ports/rs_port/Cargo.toml' - - 'source/ports/rs_port/inline/Cargo.toml' + - 'source/ports/rs_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -15,9 +16,39 @@ env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} jobs: + test: + name: Rust Port Tests + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - name: Check out the repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install MetaCall Unix + if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + run: curl -sL https://raw.githubusercontent.com/metacall/install/master/install.sh | sh + - name: Install MetaCall Windows + if: matrix.os == 'windows-latest' + run: powershell -NoProfile -ExecutionPolicy Unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/metacall/install/master/install.ps1')))" + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Build and Test the Rust Port + working-directory: source/ports/rs_port + run: | + cargo build --verbose + cargo test --verbose + release: name: Release Rust Port runs-on: ubuntu-latest + needs: test steps: - name: Check out the repo uses: actions/checkout@v4 diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 4b7bcf309..1c623ca2f 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -1,4 +1,147 @@ -use std::env; +use std::{ + env, fs, + path::{Path, PathBuf}, + vec, +}; + +// Search for MetaCall libraries in platform-specific locations +// Handle custom installation paths via environment variables +// Find configuration files recursively +// Provide helpful error messages when things aren't found + +/// Represents the install paths for a platform +struct InstallPath { + paths: Vec<PathBuf>, + names: Vec<&'static str>, +} + +/// Find files recursively in a directory matching a pattern +fn find_files_recursively<P: AsRef<Path>>( + root_dir: P, + filename: &str, + max_depth: Option<usize>, +) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> { + let mut matches = Vec::new(); + let mut stack = vec![(root_dir.as_ref().to_path_buf(), 0)]; + + while let Some((current_dir, depth)) = stack.pop() { + if let Some(max) = max_depth { + if depth > max { + continue; + } + } + + if let Ok(entries) = fs::read_dir(¤t_dir) { + for entry in entries.flatten() { + let path = entry.path(); + + if path.is_file() { + // Simple filename comparison instead of regex + if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { + if file_name == filename { + matches.push(path); + } + } + } else if path.is_dir() { + stack.push((path, depth + 1)); + } + } + } + } + + Ok(matches) +} + +fn platform_install_paths() -> Result<InstallPath, Box<dyn std::error::Error>> { + if cfg!(target_os = "windows") { + // Defaults to path: C:\Users\Default\AppData\Local + let local_app_data = env::var("LOCALAPPDATA") + .unwrap_or_else(|_| String::from("C:\\Users\\Default\\AppData\\Local")); + + Ok(InstallPath { + paths: vec![PathBuf::from(local_app_data) + .join("MetaCall") + .join("metacall")], + names: vec!["metacall.dll"], + }) + } else if cfg!(target_os = "macos") { + Ok(InstallPath { + paths: vec![ + PathBuf::from("/opt/homebrew/lib/"), + PathBuf::from("/usr/local/lib/"), + ], + names: vec!["metacall.dylib"], + }) + } else if cfg!(target_os = "linux") { + Ok(InstallPath { + paths: vec![PathBuf::from("/usr/local/lib/"), PathBuf::from("/gnu/lib/")], + names: vec!["libmetacall.so"], + }) + } else { + Err(format!("Platform {} not supported", env::consts::OS).into()) + } +} + +/// Get search paths, checking for custom installation path first +fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { + // First, check if user specified a custom path + if let Ok(custom_path) = env::var("METACALL_INSTALL_PATH") { + // For custom paths, we need to search for any metacall library variant + return Ok(InstallPath { + paths: vec![PathBuf::from(custom_path)], + names: vec!["libmetacall.so", "libmetacalld.so", "libmetacall.dylib", "libmetacalld.dylib", "metacall.dll", "metacalld.dll"] + }); + } + + // Fall back to platform-specific paths + platform_install_paths() +} + +/// Find the MetaCall library +/// This orchestrates the search process +fn find_metacall_library() -> Result<PathBuf, Box<dyn std::error::Error>> { + let search_config = get_search_config()?; + + // Search in each configured path + for search_path in &search_config.paths { + for name in &search_config.names { + // Search with no limit in depth + match find_files_recursively(search_path, &name.to_string(), None) { + Ok(files) if !files.is_empty() => { + let found_lib = fs::canonicalize(&files[0])?; + + return Ok(found_lib.clone()); + } + Ok(_) => { + // No files found in this path, continue searching + continue; + } + Err(e) => { + eprintln!( + "Error searching in {}: {}", + search_path.display(), + e + ); + continue; + } + } + } + } + + // If we get here, library wasn't found + let search_paths: Vec<String> = search_config + .paths + .iter() + .map(|p| p.display().to_string()) + .collect(); + + Err(format!( + "MetaCall library not found. Searched in: {}. \ + If you have it installed elsewhere, set METACALL_INSTALL_PATH environment variable.", + search_paths.join(", ") + ) + .into()) +} fn main() { // When running tests from CMake @@ -21,16 +164,21 @@ fn main() { } } } else { - // When building from Cargo - let profile = env::var("PROFILE").unwrap(); - match profile.as_str() { - // "debug" => { - // println!("cargo:rustc-link-lib=dylib=metacalld"); - // } - "debug" | "release" => { - println!("cargo:rustc-link-lib=dylib=metacall") + // When building from Cargo, try to find MetaCall + match find_metacall_library() { + Ok(lib_path) => { + // Extract the directory containing the library + if let Some(lib_dir) = lib_path.parent() { + println!("cargo:rustc-link-search=native={}", lib_dir.display()); + println!("cargo:rustc-link-lib=dylib=metacall"); + } } - _ => { + Err(e) => { + // Print the error + eprintln!("Failed to find MetaCall library with: {e} \ + Still trying to link in case the library is in system paths"); + + // Still try to link in case the library is in system paths println!("cargo:rustc-link-lib=dylib=metacall") } } From 57641a6a6815fb8dfa1f93c35e62e31def0ef2d3 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 4 Sep 2025 17:05:19 +0200 Subject: [PATCH 075/109] Improve tcc support on C Loader. --- source/loaders/c_loader/source/c_loader_impl.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index c041ffc5c..3fffb19ec 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -1443,6 +1443,15 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas return data.result; } +static int c_loader_impl_tcc_relocate(TCCState *state) +{ +#ifdef TCC_RELOCATE_AUTO + return tcc_relocate(state, TCC_RELOCATE_AUTO); +#else + return tcc_relocate(state); +#endif +} + loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path paths[], size_t size) { loader_impl_c c_impl = static_cast<loader_impl_c>(loader_impl_get(impl)); @@ -1497,7 +1506,7 @@ loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path p } } - if (tcc_relocate(c_handle->state) == -1) + if (c_loader_impl_tcc_relocate(c_handle->state) == -1) { log_write("metacall", LOG_LEVEL_ERROR, "TCC failed to relocate"); goto error; @@ -1529,7 +1538,7 @@ loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name goto error; } - if (tcc_relocate(c_handle->state) == -1) + if (c_loader_impl_tcc_relocate(c_handle->state) == -1) { log_write("metacall", LOG_LEVEL_ERROR, "TCC failed to relocate"); goto error; From b34f79780ca0c2ea189fc5bce3acfcddb1aa3cc5 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 4 Sep 2025 17:05:33 +0200 Subject: [PATCH 076/109] Solve issue with MacOS CMake. --- .github/workflows/macos-test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/macos-test.yml b/.github/workflows/macos-test.yml index 2a5725996..520de1517 100644 --- a/.github/workflows/macos-test.yml +++ b/.github/workflows/macos-test.yml @@ -40,6 +40,10 @@ jobs: with: fetch-depth: 0 + - name: Uninstall CMake + run: | + brew uninstall --force cmake + - name: Uninstall NodeJS and NPM run: | npm uninstall npm -g From 832cbb4048ad296f9c6838a70b456e32483d0f9f Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 4 Sep 2025 17:10:52 +0200 Subject: [PATCH 077/109] Remove release of rust ci from PR and workflow dispatch. --- .github/workflows/release-rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 13644cd0f..6d2f0897f 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -49,6 +49,7 @@ jobs: name: Release Rust Port runs-on: ubuntu-latest needs: test + if: ${{ github.event_name != 'workflow_dispatch' && github.event_name != 'pull_request' }} steps: - name: Check out the repo uses: actions/checkout@v4 From 6afe9bef2a62c1dce103063e25b42062af67cb74 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 4 Sep 2025 17:23:29 +0200 Subject: [PATCH 078/109] Update version to v0.9.14. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6af8ded76..69010fa5b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.13 \ No newline at end of file +0.9.14 \ No newline at end of file From 4e91b7094ef52a15fcb6d56e00ea105fc8d42739 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 4 Sep 2025 18:11:54 +0200 Subject: [PATCH 079/109] Solve cmake issue in macos benchmarks ci. --- .github/workflows/benchmark.yml | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 06b428b84..67a684cd0 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -32,9 +32,41 @@ jobs: with: fetch-depth: 0 - - name: Export XCode SDK Root + - name: Prepare MacOS Installation if: matrix.os == 'macos-latest' - run: echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV + run: | + echo "Uninstall CMake" + brew uninstall --force cmake + + echo "Uninstall NodeJS and NPM" + npm uninstall npm -g + rm -rf /usr/local/lib/node_modules/npm + + echo "Uninstall Ruby" + brew uninstall --force --ignore-dependencies ruby + brew cleanup -s ruby + brew cleanup --prune-prefix + RUBY_FRAMEWORK_DIR=$(xcrun --sdk macosx --show-sdk-path)/System/Library/Frameworks/Ruby.framework + sudo rm -rf $RUBY_FRAMEWORK_DIR + + echo "Uninstall Go" + brew uninstall --force go + brew autoremove + sudo rm -rf /usr/local/Cellar/go + sudo rm -rf /usr/local/go + sudo rm -rf /usr/local/opt/go + sudo rm -rf /etc/paths.d/go + sudo rm -rf /usr/local/bin/go + sudo rm -rf /usr/local/bin/gofmt + + echo "Uninstall Java" + sudo rm -rf /Library/Java/JavaVirtualMachines/* + sudo rm -rf /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin + sudo rm -rf /Library/PreferencePanes/JavaControlPanel.prefPane + unset JAVA_HOME + + echo "Export XCode SDK Root" + echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV # TODO: Add support for NetCore Bench - name: Set up the environment From 59e7b9141c81c7c0861b6759f7428932541392c4 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 00:44:33 +0200 Subject: [PATCH 080/109] Solve more issues in build.rs. --- source/ports/rs_port/build.rs | 63 +++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 1c623ca2f..e1fe1464e 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -15,6 +15,12 @@ struct InstallPath { names: Vec<&'static str>, } +/// Represents the match of a library when it's found +struct LibraryPath { + path: PathBuf, + library: String, +} + /// Find files recursively in a directory matching a pattern fn find_files_recursively<P: AsRef<Path>>( root_dir: P, @@ -70,7 +76,7 @@ fn platform_install_paths() -> Result<InstallPath, Box<dyn std::error::Error>> { PathBuf::from("/opt/homebrew/lib/"), PathBuf::from("/usr/local/lib/"), ], - names: vec!["metacall.dylib"], + names: vec!["libmetacall.dylib"], }) } else if cfg!(target_os = "linux") { Ok(InstallPath { @@ -89,7 +95,14 @@ fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { // For custom paths, we need to search for any metacall library variant return Ok(InstallPath { paths: vec![PathBuf::from(custom_path)], - names: vec!["libmetacall.so", "libmetacalld.so", "libmetacall.dylib", "libmetacalld.dylib", "metacall.dll", "metacalld.dll"] + names: vec![ + "libmetacall.so", + "libmetacalld.so", + "libmetacall.dylib", + "libmetacalld.dylib", + "metacall.dll", + "metacalld.dll", + ], }); } @@ -97,31 +110,48 @@ fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { platform_install_paths() } +/// Get the parent path and library name +fn get_parent_and_library(path: &Path) -> Option<(PathBuf, String)> { + let parent = path.parent()?.to_path_buf(); + + // Get the file stem (filename without extension) + let stem = path.file_stem()?.to_str()?; + + // Remove "lib" prefix if present + let cleaned_stem = stem.strip_prefix("lib").unwrap_or(stem).to_string(); + + Some((parent, cleaned_stem)) +} + /// Find the MetaCall library /// This orchestrates the search process -fn find_metacall_library() -> Result<PathBuf, Box<dyn std::error::Error>> { +fn find_metacall_library() -> Result<LibraryPath, Box<dyn std::error::Error>> { let search_config = get_search_config()?; // Search in each configured path for search_path in &search_config.paths { for name in &search_config.names { // Search with no limit in depth - match find_files_recursively(search_path, &name.to_string(), None) { + match find_files_recursively(search_path, name, None) { Ok(files) if !files.is_empty() => { let found_lib = fs::canonicalize(&files[0])?; - return Ok(found_lib.clone()); + match get_parent_and_library(&found_lib) { + Some((parent, name)) => { + return Ok(LibraryPath { + path: parent, + library: name, + }) + } + None => continue, + }; } Ok(_) => { // No files found in this path, continue searching continue; } Err(e) => { - eprintln!( - "Error searching in {}: {}", - search_path.display(), - e - ); + eprintln!("Error searching in {}: {}", search_path.display(), e); continue; } } @@ -167,16 +197,15 @@ fn main() { // When building from Cargo, try to find MetaCall match find_metacall_library() { Ok(lib_path) => { - // Extract the directory containing the library - if let Some(lib_dir) = lib_path.parent() { - println!("cargo:rustc-link-search=native={}", lib_dir.display()); - println!("cargo:rustc-link-lib=dylib=metacall"); - } + println!("cargo:rustc-link-search=native={}", lib_path.path.display()); + println!("cargo:rustc-link-lib=dylib={}", lib_path.library); } Err(e) => { // Print the error - eprintln!("Failed to find MetaCall library with: {e} \ - Still trying to link in case the library is in system paths"); + eprintln!( + "Failed to find MetaCall library with: {e} \ + Still trying to link in case the library is in system paths" + ); // Still try to link in case the library is in system paths println!("cargo:rustc-link-lib=dylib=metacall") From 8364cf74007a1007665c394de579c24a67d5fa55 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 01:04:50 +0200 Subject: [PATCH 081/109] Solve issues with cargo test. --- source/ports/rs_port/build.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index e1fe1464e..96502c30b 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -197,8 +197,25 @@ fn main() { // When building from Cargo, try to find MetaCall match find_metacall_library() { Ok(lib_path) => { + // Define linker flags println!("cargo:rustc-link-search=native={}", lib_path.path.display()); println!("cargo:rustc-link-lib=dylib={}", lib_path.library); + + // Set the runtime environment variable for finding the library during tests + #[cfg(target_os = "linux")] + println!( + "cargo:rustc-env=LD_LIBRARY_PATH={}", + lib_path.path.display() + ); + + #[cfg(target_os = "macos")] + println!( + "cargo:rustc-env=DYLD_LIBRARY_PATH={}", + lib_path.path.display() + ); + + #[cfg(target_os = "windows")] + println!("cargo:rustc-env=PATH={}", lib_path.path.display()); } Err(e) => { // Print the error From 9d153cb945c2b5193807e6bdfa1a18a32685a86c Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 01:19:44 +0200 Subject: [PATCH 082/109] Comment out windows in rs_port ci. --- .github/workflows/release-rust.yml | 2 +- source/ports/rs_port/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 6d2f0897f..a660c4597 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] # TODO: windows-latest steps: - name: Check out the repo uses: actions/checkout@v4 diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index d1030b99d..4779e08f0 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" name = "metacall" readme = "README.md" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" -version = "0.4.3" +version = "0.4.4" [lib] crate-type = ["lib"] From 2c06892ffad1a676ddc1574dfd1ff4e2aeb29bbf Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 17:24:05 +0200 Subject: [PATCH 083/109] Trying to solve issues with windows on rs_port. --- .github/workflows/release-rust.yml | 2 +- source/ports/rs_port/src/types/metacall_value.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index a660c4597..6d2f0897f 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] # TODO: windows-latest + os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: Check out the repo uses: actions/checkout@v4 diff --git a/source/ports/rs_port/src/types/metacall_value.rs b/source/ports/rs_port/src/types/metacall_value.rs index bbc5870ff..111dbd590 100644 --- a/source/ports/rs_port/src/types/metacall_value.rs +++ b/source/ports/rs_port/src/types/metacall_value.rs @@ -162,10 +162,10 @@ impl MetaCallValue for i64 { fn from_metacall_raw_leak(v: *mut c_void) -> Result<Self, Box<dyn MetaCallValue>> { let value = unsafe { metacall_value_to_long(v) }; - Ok(value) + Ok(value as i64) } fn into_metacall_raw(self) -> *mut c_void { - unsafe { metacall_value_create_long(self) } + unsafe { metacall_value_create_long(self.try_into().unwrap()) } } } /// Equivalent to MetaCall float type. From a1eb88f2bf7994b00f2fa46e2a90948ea29050e3 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 17:41:04 +0200 Subject: [PATCH 084/109] Add load from memory in c loader. --- .../loaders/c_loader/source/c_loader_impl.cpp | 241 ++++++++++-------- .../source/metacall_c_test.cpp | 20 +- 2 files changed, 146 insertions(+), 115 deletions(-) diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index 3fffb19ec..70470488c 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -76,12 +76,42 @@ typedef struct loader_impl_c_type } * loader_impl_c; +struct loader_impl_c_handle_base_type; + +typedef struct loader_impl_c_handle_base_type *loader_impl_c_handle_base; + +typedef struct c_loader_impl_discover_visitor_data_type +{ + loader_impl impl; + loader_impl_c_handle_base c_handle; + scope sp; + int result; + +} * c_loader_impl_discover_visitor_data; + +static CXChildVisitResult c_loader_impl_discover_visitor(CXCursor cursor, CXCursor, void *data); + typedef struct loader_impl_c_handle_base_type { +public: + virtual ~loader_impl_c_handle_base_type() {} + + virtual bool recursive_includes() = 0; + + virtual int discover(loader_impl impl, context ctx) = 0; + + virtual const void *symbol(std::string &name) = 0; + + virtual int discover_visitor(std::vector<const char *> &command_line_args, void *data) = 0; + +} * loader_impl_c_handle_base; + +typedef struct loader_impl_c_handle_file_type : loader_impl_c_handle_base_type +{ public: std::vector<std::string> files; - virtual ~loader_impl_c_handle_base_type() {} + virtual ~loader_impl_c_handle_file_type() {} virtual bool recursive_includes() = 0; @@ -89,6 +119,38 @@ typedef struct loader_impl_c_handle_base_type virtual const void *symbol(std::string &name) = 0; + int discover_visitor(std::vector<const char *> &command_line_args, void *data) + { + for (std::string file : this->files) + { + /* Define the command line arguments (simulating compiler flags) */ + CXIndex index = clang_createIndex(0, 1); + CXTranslationUnit unit = NULL; + CXErrorCode error = clang_parseTranslationUnit2( + index, + file.c_str(), + command_line_args.data(), command_line_args.size(), + nullptr, 0, + CXTranslationUnit_None, + &unit); + + if (error != CXError_Success) + { + log_write("metacall", LOG_LEVEL_ERROR, "Unable to parse translation unit of: %s with error code %d", file.c_str(), error); + clang_disposeIndex(index); + return -1; + } + + CXCursor cursor = clang_getTranslationUnitCursor(unit); + clang_visitChildren(cursor, c_loader_impl_discover_visitor, data); + + clang_disposeTranslationUnit(unit); + clang_disposeIndex(index); + } + + return 0; + } + void add(const loader_path path, size_t size) { if (this->is_ld_script(path, size) == false) @@ -118,12 +180,65 @@ typedef struct loader_impl_c_handle_base_type return true; } -} * loader_impl_c_handle_base; +} * loader_impl_c_handle_file; + +typedef struct loader_impl_c_handle_memory_type : loader_impl_c_handle_base_type +{ +public: + std::string name; + std::string buffer; + + virtual ~loader_impl_c_handle_memory_type() {} + + virtual bool recursive_includes() = 0; + + virtual int discover(loader_impl impl, context ctx) = 0; + + virtual const void *symbol(std::string &name) = 0; + + int discover_visitor(std::vector<const char *> &command_line_args, void *data) + { + CXUnsavedFile unsaved_file; + + /* Simulate an in-memory file */ + unsaved_file.Filename = this->name.c_str(); + unsaved_file.Contents = this->buffer.c_str(); + unsaved_file.Length = this->buffer.length(); + + /* Define the command line arguments (simulating compiler flags) */ + CXIndex index = clang_createIndex(0, 1); + CXTranslationUnit unit = NULL; + CXErrorCode error = clang_parseTranslationUnit2( + index, + this->name.c_str(), + command_line_args.data(), command_line_args.size(), + &unsaved_file, 1, + CXTranslationUnit_None, + &unit); + + if (error != CXError_Success) + { + log_write("metacall", LOG_LEVEL_ERROR, "Unable to parse translation unit of: %s with error code %d", this->name.c_str(), error); + clang_disposeIndex(index); + return -1; + } + + CXCursor cursor = clang_getTranslationUnitCursor(unit); + clang_visitChildren(cursor, c_loader_impl_discover_visitor, data); + + clang_disposeTranslationUnit(unit); + clang_disposeIndex(index); + + return 0; + } + +} * loader_impl_c_handle_memory; static void c_loader_impl_discover_symbols(void *ctx, const char *name, const void *addr); static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_base c_handle, context ctx); -typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type +template <typename T> +struct loader_impl_c_handle_tcc_type : T { public: TCCState *state; @@ -207,7 +322,7 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type virtual int discover(loader_impl impl, context ctx) { /* Get all symbols */ - tcc_list_symbols(this->state, static_cast<void *>(this), &c_loader_impl_discover_symbols); + tcc_list_symbols(this->state, static_cast<void *>(&symbols), &c_loader_impl_discover_symbols); /* Parse the AST and register functions */ return c_loader_impl_discover_ast(impl, this, ctx); @@ -222,10 +337,15 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type return this->symbols[name]; } +}; + +typedef struct loader_impl_c_handle_tcc_type<loader_impl_c_handle_file_type> loader_impl_c_handle_tcc_file_type; +typedef loader_impl_c_handle_tcc_file_type *loader_impl_c_handle_tcc_file; -} * loader_impl_c_handle_tcc; +typedef struct loader_impl_c_handle_tcc_type<loader_impl_c_handle_memory_type> loader_impl_c_handle_tcc_memory_type; +typedef loader_impl_c_handle_tcc_memory_type *loader_impl_c_handle_tcc_memory; -typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_type +typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_file_type { public: dynlink lib; @@ -385,15 +505,6 @@ typedef struct loader_impl_c_function_type } * loader_impl_c_function; -typedef struct c_loader_impl_discover_visitor_data_type -{ - loader_impl impl; - loader_impl_c_handle_base c_handle; - scope sp; - int result; - -} * c_loader_impl_discover_visitor_data; - /* Retrieve the equivalent FFI type from type id */ static ffi_type *c_loader_impl_ffi_type(type_id id); @@ -681,9 +792,9 @@ void c_loader_impl_function_closure(ffi_cif *cif, void *ret, void *args[], void static void c_loader_impl_discover_symbols(void *ctx, const char *name, const void *addr) { - loader_impl_c_handle_tcc c_handle = static_cast<loader_impl_c_handle_tcc>(ctx); + std::map<std::string, const void *> *symbols = static_cast<std::map<std::string, const void *> *>(ctx); - c_handle->symbols.insert(std::pair<std::string, const void *>(name, addr)); + symbols->insert(std::pair<std::string, const void *>(name, addr)); } static bool c_loader_impl_file_exists(const loader_path path) @@ -1305,7 +1416,7 @@ static int c_loader_impl_discover_signature(loader_impl impl, loader_impl_c_hand return 0; } -static CXChildVisitResult c_loader_impl_discover_visitor(CXCursor cursor, CXCursor, void *data) +CXChildVisitResult c_loader_impl_discover_visitor(CXCursor cursor, CXCursor, void *data) { c_loader_impl_discover_visitor_data visitor_data = static_cast<c_loader_impl_discover_visitor_data>(data); @@ -1353,91 +1464,9 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas command_line_args.push_back(includes.back().c_str()); } - /* TODO: Load from memory (discover from memory) */ - /* - #include <clang-c/Index.h> - #include <stdio.h> - #include <stdlib.h> - - int main() { - const char *source_code = - "int add(int a, int b) {\n" - " return a + b;\n" - "}"; - - // Simulate an in-memory file - CXUnsavedFile unsaved_file; - unsaved_file.Filename = "example.c"; - unsaved_file.Contents = source_code; - unsaved_file.Length = (unsigned long)strlen(source_code); - - // Create index - CXIndex index = clang_createIndex(0, 0); - - // Parse translation unit from buffer (unsaved file) - CXTranslationUnit tu; - CXErrorCode err = clang_parseTranslationUnit2( - index, - "example.c", // filename for context (matches unsaved file) - NULL, 0, // command line args - &unsaved_file, 1, // unsaved files - CXTranslationUnit_None, // options - &tu - ); - - if (err != CXError_Success) { - fprintf(stderr, "Failed to parse translation unit.\n"); - return 1; - } - - // Get the cursor to the root of the translation unit - CXCursor cursor = clang_getTranslationUnitCursor(tu); - - // Visit each AST node - clang_visitChildren( - cursor, - [](CXCursor c, CXCursor parent, CXClientData client_data) { - CXString spelling = clang_getCursorSpelling(c); - CXString kind = clang_getCursorKindSpelling(clang_getCursorKind(c)); - printf("Cursor: %s (%s)\n", clang_getCString(spelling), clang_getCString(kind)); - clang_disposeString(spelling); - clang_disposeString(kind); - return CXChildVisit_Recurse; - }, - NULL - ); - - // Clean up - clang_disposeTranslationUnit(tu); - clang_disposeIndex(index); - - return 0; - } - */ - - for (std::string file : c_handle->files) + if (c_handle->discover_visitor(command_line_args, static_cast<void *>(&data)) != 0) { - /* Define the command line arguments (simulating compiler flags) */ - CXIndex index = clang_createIndex(0, 1); - CXTranslationUnit unit = clang_parseTranslationUnit( - index, - file.c_str(), - command_line_args.data(), command_line_args.size(), - nullptr, 0, - CXTranslationUnit_None); - - if (unit == nullptr) - { - log_write("metacall", LOG_LEVEL_ERROR, "Unable to parse translation unit of: %s", file.c_str()); - clang_disposeIndex(index); - return -1; - } - - CXCursor cursor = clang_getTranslationUnitCursor(unit); - clang_visitChildren(cursor, c_loader_impl_discover_visitor, static_cast<void *>(&data)); - - clang_disposeTranslationUnit(unit); - clang_disposeIndex(index); + return 1; } return data.result; @@ -1455,7 +1484,7 @@ static int c_loader_impl_tcc_relocate(TCCState *state) loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path paths[], size_t size) { loader_impl_c c_impl = static_cast<loader_impl_c>(loader_impl_get(impl)); - loader_impl_c_handle_tcc c_handle = new loader_impl_c_handle_tcc_type(); + loader_impl_c_handle_tcc_file c_handle = new loader_impl_c_handle_tcc_file_type(); if (c_handle->initialize(c_impl) == false) { @@ -1522,7 +1551,7 @@ loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path p loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name name, const char *buffer, size_t size) { loader_impl_c c_impl = static_cast<loader_impl_c>(loader_impl_get(impl)); - loader_impl_c_handle_tcc c_handle = new loader_impl_c_handle_tcc_type(); + loader_impl_c_handle_tcc_memory c_handle = new loader_impl_c_handle_tcc_memory_type(); /* Apparently TCC has an unsafe API for compiling strings */ (void)size; @@ -1544,7 +1573,9 @@ loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name goto error; } - /* TODO: Load the buffer with the parser while iterating after loading it with TCC */ + c_handle->name = name; + c_handle->name.append(".c"); + c_handle->buffer.assign(buffer, size); return c_handle; diff --git a/source/tests/metacall_c_test/source/metacall_c_test.cpp b/source/tests/metacall_c_test/source/metacall_c_test.cpp index b661e8b39..9b4bf3f6b 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -284,21 +284,21 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_value_destroy(args[0]); /* Memory */ - // TODO - // const char c_buffer[] = { - // "int compiled_mult(int a, int b) { return a * b; }" - // }; + { + const char c_buffer[] = { + "int compiled_mult_memory(int a, int b) { return a * b; }" + }; - // EXPECT_EQ((int)0, (int)metacall_load_from_memory("c", c_buffer, sizeof(c_buffer), NULL)); + EXPECT_EQ((int)0, (int)metacall_load_from_memory("c", c_buffer, sizeof(c_buffer), NULL)); - // TODO - // void *ret = metacall("compiled_mult", 3, 4); + void *ret = metacall("compiled_mult_memory", 3, 4); - // EXPECT_NE((void *)NULL, (void *)ret); + EXPECT_NE((void *)NULL, (void *)ret); - // EXPECT_EQ((int)metacall_value_to_int(ret), (int)0); + EXPECT_EQ((int)metacall_value_to_int(ret), (int)12); - // metacall_value_destroy(ret); + metacall_value_destroy(ret); + } /* References (Native) */ { From fce639c6fa420eb3aa041286f66b35c928de2013 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Fri, 5 Sep 2025 17:41:35 +0200 Subject: [PATCH 085/109] Solve issues in rust port. --- source/ports/rs_port/build.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 96502c30b..3ad13b15d 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -68,7 +68,7 @@ fn platform_install_paths() -> Result<InstallPath, Box<dyn std::error::Error>> { paths: vec![PathBuf::from(local_app_data) .join("MetaCall") .join("metacall")], - names: vec!["metacall.dll"], + names: vec!["metacall.lib"], }) } else if cfg!(target_os = "macos") { Ok(InstallPath { @@ -100,8 +100,8 @@ fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { "libmetacalld.so", "libmetacall.dylib", "libmetacalld.dylib", - "metacall.dll", - "metacalld.dll", + "metacall.lib", + "metacalld.lib", ], }); } From 301d17ba86cbeb26ae916f5f3f8f8754bf9d034d Mon Sep 17 00:00:00 2001 From: Fahd Ashour <fahd.fady212@gmail.com> Date: Mon, 8 Sep 2025 23:26:20 +0300 Subject: [PATCH 086/109] remove usage of metacall::switch and some edits in Rust docs (#573) * remove usage of metacall::switch and some edits in Rust docs * edit rs_port readme to metacall 4.4 Signed-off-by: fahdfady <fahd.fady212@gmail.com> --------- Signed-off-by: fahdfady <fahd.fady212@gmail.com> --- source/ports/rs_port/README.md | 4 ++-- source/ports/rs_port/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ports/rs_port/README.md b/source/ports/rs_port/README.md index 06f77ab06..8b9a5531c 100644 --- a/source/ports/rs_port/README.md +++ b/source/ports/rs_port/README.md @@ -26,11 +26,11 @@ export function sum(a: number, b: number): number { `main.rs` ``` rust -use metacall::{switch, metacall, loaders}; +use metacall::{initialize, metacall, load}; fn main() { // Initialize MetaCall at the top - let _metacall = switch::initialize().unwrap(); + let _metacall = initialize().unwrap(); // Load the file load::from_single_file("ts", "sum.ts").unwrap(); diff --git a/source/ports/rs_port/src/lib.rs b/source/ports/rs_port/src/lib.rs index 328236d57..3cfb34485 100644 --- a/source/ports/rs_port/src/lib.rs +++ b/source/ports/rs_port/src/lib.rs @@ -41,11 +41,11 @@ //! Now let's jump into Rust: //! //! ``` -//! use metacall::{switch, metacall, loaders}; +//! use metacall::{initialize, metacall, load}; //! //! fn main() { //! // Initialize MetaCall at the top -//! let _metacall = switch::initialize().unwrap(); +//! let _metacall = initialize().unwrap(); //! //! // Load the file (Checkout the loaders module for loading multiple files //! // or loading from string) From 6caae7aa6e4816bf7966331be0b40d5d5322cc6a Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Mon, 8 Sep 2025 22:35:01 +0200 Subject: [PATCH 087/109] Upgrade rs_port version. --- source/ports/rs_port/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index 4779e08f0..c0ce796a1 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" name = "metacall" readme = "README.md" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" -version = "0.4.4" +version = "0.5.0" [lib] crate-type = ["lib"] From 59eaec0c6b222d4ae0fa6ceef61474487723fa19 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Mon, 8 Sep 2025 23:00:36 +0200 Subject: [PATCH 088/109] Remove windows from rust ci. --- .github/workflows/release-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 6d2f0897f..c06c473b8 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] # TODO: , windows-latest] steps: - name: Check out the repo uses: actions/checkout@v4 From fbb721bfced23ce137f64f943f61bfba43899d52 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Mon, 8 Sep 2025 23:05:31 +0200 Subject: [PATCH 089/109] Update rust ci. --- .github/workflows/release-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index c06c473b8..528eda6b7 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -49,7 +49,7 @@ jobs: name: Release Rust Port runs-on: ubuntu-latest needs: test - if: ${{ github.event_name != 'workflow_dispatch' && github.event_name != 'pull_request' }} + if: ${{ github.event_name != 'pull_request' }} steps: - name: Check out the repo uses: actions/checkout@v4 From 9073c1c3f62f4db8a470abdb185ae052562dd810 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 9 Sep 2025 21:53:35 +0200 Subject: [PATCH 090/109] Improved portability of rs port. --- source/ports/rs_port/build.rs | 41 +- source/ports/rs_port/src/bindings.rs | 1439 +++++++++++++++++++++++++- 2 files changed, 1470 insertions(+), 10 deletions(-) diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 3ad13b15d..98e2596bf 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -173,6 +173,21 @@ fn find_metacall_library() -> Result<LibraryPath, Box<dyn std::error::Error>> { .into()) } +fn define_library_search_path(env_var: &str, separator: &str, path: &PathBuf) -> String { + // Get the current value of the env var, if any + let existing = env::var(env_var).unwrap_or_default(); + let path_str: String = String::from(path.to_str().unwrap()); + + // Append to it + let combined = if existing.is_empty() { + path_str + } else { + format!("{}{}{}", existing, separator, path_str) + }; + + format!("{}={}", env_var, combined) +} + fn main() { // When running tests from CMake if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") { @@ -203,19 +218,27 @@ fn main() { // Set the runtime environment variable for finding the library during tests #[cfg(target_os = "linux")] - println!( - "cargo:rustc-env=LD_LIBRARY_PATH={}", - lib_path.path.display() - ); + const ENV_VAR: &str = "LD_LIBRARY_PATH"; #[cfg(target_os = "macos")] - println!( - "cargo:rustc-env=DYLD_LIBRARY_PATH={}", - lib_path.path.display() - ); + const ENV_VAR: &str = "DYLD_LIBRARY_PATH"; #[cfg(target_os = "windows")] - println!("cargo:rustc-env=PATH={}", lib_path.path.display()); + const ENV_VAR: &str = "PATH"; + + #[cfg(target_os = "aix")] + const ENV_VAR: &str = "LIBPATH"; + + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "aix"))] + const SEPARATOR: &str = ":"; + + #[cfg(target_os = "windows")] + const SEPARATOR: &str = ";"; + + println!( + "cargo:rustc-env={}", + define_library_search_path(ENV_VAR, SEPARATOR, &lib_path.path) + ); } Err(e) => { // Print the error diff --git a/source/ports/rs_port/src/bindings.rs b/source/ports/rs_port/src/bindings.rs index 7222ae744..04c9be017 100644 --- a/source/ports/rs_port/src/bindings.rs +++ b/source/ports/rs_port/src/bindings.rs @@ -1,3 +1,1440 @@ /* automatically generated by rust-bindgen 0.71.1 */ -pub type __pid_t = :: std :: os :: raw :: c_int ; pub type pid_t = __pid_t ; # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_allocator_id { METACALL_ALLOCATOR_STD = 0 , METACALL_ALLOCATOR_NGINX = 1 , } unsafe extern "C" { # [doc = " @brief\n Create an allocator instance\n\n @param[in] allocator_id\n Type of allocator to be created\n\n @param[in] ctx\n Context of the allocator\n\n @return\n Pointer to allocator if success, null otherwise"] pub fn metacall_allocator_create (allocator_id : metacall_allocator_id , ctx : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Reserve memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] size\n Size in bytes to be allocated\n\n @return\n Pointer to allocated data on success, null otherwise"] pub fn metacall_allocator_alloc (allocator : * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Reallocate memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Original pointer to data\n\n @param[in] size\n Original size in bytes\n\n @param[in] new_size\n New size in bytes to be reallocated\n\n @return\n Pointer to new reallocated data on success, null otherwise"] pub fn metacall_allocator_realloc (allocator : * mut :: std :: os :: raw :: c_void , data : * mut :: std :: os :: raw :: c_void , size : usize , new_size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Free memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Pointer to data to be freed"] pub fn metacall_allocator_free (allocator : * mut :: std :: os :: raw :: c_void , data : * mut :: std :: os :: raw :: c_void) ; } unsafe extern "C" { # [doc = " @brief\n Destroy an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance"] pub fn metacall_allocator_destroy (allocator : * mut :: std :: os :: raw :: c_void) ; } # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_exception_type { pub message : * const :: std :: os :: raw :: c_char , pub label : * const :: std :: os :: raw :: c_char , pub code : i64 , pub stacktrace : * const :: std :: os :: raw :: c_char , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_exception_type"] [:: std :: mem :: size_of :: < metacall_exception_type > () - 32usize] ; ["Alignment of metacall_exception_type"] [:: std :: mem :: align_of :: < metacall_exception_type > () - 8usize] ; ["Offset of field: metacall_exception_type::message"] [:: std :: mem :: offset_of ! (metacall_exception_type , message) - 0usize] ; ["Offset of field: metacall_exception_type::label"] [:: std :: mem :: offset_of ! (metacall_exception_type , label) - 8usize] ; ["Offset of field: metacall_exception_type::code"] [:: std :: mem :: offset_of ! (metacall_exception_type , code) - 16usize] ; ["Offset of field: metacall_exception_type::stacktrace"] [:: std :: mem :: offset_of ! (metacall_exception_type , stacktrace) - 24usize] ; } ; pub type metacall_exception = * mut metacall_exception_type ; unsafe extern "C" { # [doc = " @brief\n Create an throwable value from an exception with a simple API in a single instruction\n\n @param[in] label\n Label of the exception\n\n @param[in] code\n Error code of the exception\n\n @param[in] stacktrace\n Stack trace of the exception\n\n @param[in] message\n Message of the exception to be formatted with the variable arguments\n\n @param[in] va_args\n Arguments for formatting the message\n\n @return\n The value of type throwable containing the exception created"] pub fn metacall_error_throw (label : * const :: std :: os :: raw :: c_char , code : i64 , stacktrace : * const :: std :: os :: raw :: c_char , message : * const :: std :: os :: raw :: c_char , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Retrieve the exception from a value, it can be either a throwable value with an exception inside or an exception itself\n\n @param[in] v\n Value that represents the exception to be retrieved\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to @v\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_error_from_value (v : * mut :: std :: os :: raw :: c_void , ex : metacall_exception) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Retrieve last error that has happened after a call to any API from MetaCall\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to the internal MetaCall exception\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_error_last (ex : metacall_exception) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Clear last error that has happened after a call to any API from MetaCall"] pub fn metacall_error_clear () ; } unsafe extern "C" { # [doc = " @brief\n Initialize link detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_register (tag : * const :: std :: os :: raw :: c_char , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char , fn_ : :: std :: option :: Option < unsafe extern "C" fn () >) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] loader\n Pointer to the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_register_loader (loader : * mut :: std :: os :: raw :: c_void , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char , fn_ : :: std :: option :: Option < unsafe extern "C" fn () >) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Remove the hook previously registered\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_link_unregister (tag : * const :: std :: os :: raw :: c_char , library : * const :: std :: os :: raw :: c_char , symbol : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Unregister link detours and destroy shared memory"] pub fn metacall_link_destroy () ; } # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_log_id { METACALL_LOG_STDIO = 0 , METACALL_LOG_FILE = 1 , METACALL_LOG_SOCKET = 2 , METACALL_LOG_SYSLOG = 3 , METACALL_LOG_NGINX = 4 , METACALL_LOG_CUSTOM = 5 , } unsafe extern "C" { # [doc = " @brief\n Create a log instance\n\n @param[in] log_id\n Type of log to be created\n\n @param[in] ctx\n Context of the log (a pointer to metacall_log_{stdio, file, socket, syslog, nginx, custom}_type)\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_log (log_id : metacall_log_id , ctx : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } # [repr (u32)] # [derive (Debug , Copy , Clone , Hash , PartialEq , Eq)] pub enum metacall_value_id { METACALL_BOOL = 0 , METACALL_CHAR = 1 , METACALL_SHORT = 2 , METACALL_INT = 3 , METACALL_LONG = 4 , METACALL_FLOAT = 5 , METACALL_DOUBLE = 6 , METACALL_STRING = 7 , METACALL_BUFFER = 8 , METACALL_ARRAY = 9 , METACALL_MAP = 10 , METACALL_PTR = 11 , METACALL_FUTURE = 12 , METACALL_FUNCTION = 13 , METACALL_NULL = 14 , METACALL_CLASS = 15 , METACALL_OBJECT = 16 , METACALL_EXCEPTION = 17 , METACALL_THROWABLE = 18 , METACALL_SIZE = 19 , METACALL_INVALID = 20 , } unsafe extern "C" { # [doc = " @brief\n Create a value from boolean @b\n\n @param[in] b\n Boolean will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_bool (b : :: std :: os :: raw :: c_uchar) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from char @c\n\n @param[in] c\n Character will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_char (c : :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from short @s\n\n @param[in] s\n Short will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_short (s : :: std :: os :: raw :: c_short) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from integer @i\n\n @param[in] i\n Integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_int (i : :: std :: os :: raw :: c_int) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from long @l\n\n @param[in] l\n Long integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_long (l : :: std :: os :: raw :: c_long) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from single precision floating point number @f\n\n @param[in] f\n Float will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_float (f : f32) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from double precision floating point number @d\n\n @param[in] d\n Double will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_double (d : f64) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from a C string @str\n\n @param[in] str\n Constant string will be copied into value (needs to be null terminated)\n\n @param[in] length\n Length of the constant string\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_string (str_ : * const :: std :: os :: raw :: c_char , length : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value buffer from array @buffer\n\n @param[in] buffer\n Constant memory block will be copied into value array\n\n @param[in] size\n Size in bytes of data contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_buffer (buffer : * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value array from array of values @values\n\n @param[in] values\n Constant array of values will be copied into value list\n\n @param[in] size\n Number of elements contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_array (values : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value map from array of tuples @map\n\n @param[in] tuples\n Constant array of tuples will be copied into value map\n\n @param[in] size\n Number of elements contained in the map\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_map (tuples : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from pointer @ptr\n\n @param[in] ptr\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_ptr (ptr : * const :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from future @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_future (f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from function @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_function (f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from function @f binding a closure @c to it\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @param[in] c\n Pointer to closure that will be binded into function @f\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_function_closure (f : * mut :: std :: os :: raw :: c_void , c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value of type null\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_null () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from class @c\n\n @param[in] c\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_class (c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from object @o\n\n @param[in] o\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_object (o : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from exception @ex\n\n @param[in] ex\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_exception (ex : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a value from throwable @th\n\n @param[in] th\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] pub fn metacall_value_create_throwable (th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Returns the size of the value\n\n @param[in] v\n Reference to the value\n\n @return\n Size in bytes of the value"] pub fn metacall_value_size (v : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Returns the amount of values this value contains\n\n @param[in] v\n Reference to the value\n\n @return\n Number of values @v represents"] pub fn metacall_value_count (v : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Provide type id of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return type id assigned to value"] pub fn metacall_value_id (v : * mut :: std :: os :: raw :: c_void) -> metacall_value_id ; } unsafe extern "C" { # [doc = " @brief\n Provide type id in a readable form (as string) of a type id\n\n @param[in] id\n Value type identifier\n\n @return\n Return string related to the type id"] pub fn metacall_value_id_name (id : metacall_value_id) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide type id in a readable form (as string) of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return string related to the type id assigned to value"] pub fn metacall_value_type_name (v : * mut :: std :: os :: raw :: c_void) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Deep copies the value @v, the result copy resets\n the reference counter and ownership, including the finalizer\n\n @param[in] v\n Reference to the value to be copied\n\n @return\n Copy of the value @v on success, null otherwhise"] pub fn metacall_value_copy (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Creates a new pointer value, with a reference to the\n data contained inside the value @v. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n\n In this case, void *ptr is a value equivalent to int*,\n and it points directly to the integer contained in void *v.\n Note that if we destroy the value @v, the reference will\n point to already freed memory, causing use-after-free when used.\n\n @param[in] v\n Reference to the value to be referenced\n\n @return\n A new value of type pointer, pointing to the @v data"] pub fn metacall_value_reference (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n If you pass a reference previously created (i.e a value of\n type pointer, pointing to another value), it returns the\n original value. It does not modify the memory of the values\n neither allocates anything. If the value @v is pointing to\n has been deleted, it will cause an use-after-free. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n void *w = metacall_value_dereference(ptr);\n assert(v == w); // Both are the same value\n\n @param[in] v\n Reference to the value to be dereferenced\n\n @return\n The value containing the data which ptr is pointing to"] pub fn metacall_value_dereference (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Copies the ownership from @src to @dst, including the finalizer,\n and resets the owner and finalizer of @src\n\n @param[in] src\n Source value which will lose the ownership\n\n @param[in] dst\n Destination value which will recieve the ownership"] pub fn metacall_value_move (src : * mut :: std :: os :: raw :: c_void , dest : * mut :: std :: os :: raw :: c_void) ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to boolean\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to boolean"] pub fn metacall_value_to_bool (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_uchar ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to char\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to char"] pub fn metacall_value_to_char (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to short\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to short"] pub fn metacall_value_to_short (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_short ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to integer"] pub fn metacall_value_to_int (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to long integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to long integer"] pub fn metacall_value_to_long (v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_long ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to single precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to float"] pub fn metacall_value_to_float (v : * mut :: std :: os :: raw :: c_void) -> f32 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to double precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to dobule"] pub fn metacall_value_to_double (v : * mut :: std :: os :: raw :: c_void) -> f64 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to string\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to C string (null terminated)"] pub fn metacall_value_to_string (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to buffer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to memory block"] pub fn metacall_value_to_buffer (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to array of values\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to array of values"] pub fn metacall_value_to_array (v : * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to map\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to map (array of tuples (array of values))"] pub fn metacall_value_to_map (v : * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to pointer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to pointer"] pub fn metacall_value_to_ptr (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to future\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to future"] pub fn metacall_value_to_future (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to function\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to function"] pub fn metacall_value_to_function (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to null\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to null"] pub fn metacall_value_to_null (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to class\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to class"] pub fn metacall_value_to_class (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to object\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to object"] pub fn metacall_value_to_object (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to exception\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to exception"] pub fn metacall_value_to_exception (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v to throwable\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to throwable"] pub fn metacall_value_to_throwable (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign boolean @b to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] b\n Boolean to be assigned to value @v\n\n @return\n Value with boolean @b assigned to it"] pub fn metacall_value_from_bool (v : * mut :: std :: os :: raw :: c_void , b : :: std :: os :: raw :: c_uchar) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign character @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Character to be assigned to value @v\n\n @return\n Value with char @c assigned to it"] pub fn metacall_value_from_char (v : * mut :: std :: os :: raw :: c_void , c : :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign short @s to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] s\n Short to be assigned to value @v\n\n @return\n Value with short @s assigned to it"] pub fn metacall_value_from_short (v : * mut :: std :: os :: raw :: c_void , s : :: std :: os :: raw :: c_short) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign integer @i to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] i\n Integer to be assigned to value @v\n\n @return\n Value with integer @i assigned to it"] pub fn metacall_value_from_int (v : * mut :: std :: os :: raw :: c_void , i : :: std :: os :: raw :: c_int) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign long integer @l to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] l\n Long integer to be assigned to value @v\n\n @return\n Value with long @l assigned to it"] pub fn metacall_value_from_long (v : * mut :: std :: os :: raw :: c_void , l : :: std :: os :: raw :: c_long) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign single precision floating point @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Float to be assigned to value @v\n\n @return\n Value with float @f assigned to it"] pub fn metacall_value_from_float (v : * mut :: std :: os :: raw :: c_void , f : f32) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign double precision floating point @d to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] d\n Double to be assigned to value @v\n\n @return\n Value with double @d assigned to it"] pub fn metacall_value_from_double (v : * mut :: std :: os :: raw :: c_void , d : f64) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign string @str to value @v, truncates to @v size if it is smaller\n than @length + 1. It does not add null terminator if truncated.\n\n @param[in] v\n Reference to the value\n\n @param[in] str\n Constant string to be assigned to value @v (it needs to be null terminated)\n\n @param[in] length\n Length of the constant string @str\n\n @return\n Value with string @str assigned to it"] pub fn metacall_value_from_string (v : * mut :: std :: os :: raw :: c_void , str_ : * const :: std :: os :: raw :: c_char , length : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array @buffer to value buffer @v\n\n @param[in] v\n Reference to the value\n\n @param[in] buffer\n Constant array to be assigned to value @v\n\n @param[in] size\n Number of elements contained in @buffer\n\n @return\n Value with array @buffer assigned to it"] pub fn metacall_value_from_buffer (v : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array of values @values to value array @v\n\n @param[in] v\n Reference to the value\n\n @param[in] values\n Constant array of values to be assigned to value array @v\n\n @param[in] size\n Number of values contained in constant array @values\n\n @return\n Value with array of values @values assigned to it"] pub fn metacall_value_from_array (v : * mut :: std :: os :: raw :: c_void , values : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign array of values @values to value map @v\n\n @param[in] v\n Reference to the value\n\n @param[in] tuples\n Constant array of tuples to be assigned to value map @v\n\n @param[in] size\n Number of values contained in constant array @tuples\n\n @return\n Value with array of tuples @tuples assigned to it"] pub fn metacall_value_from_map (v : * mut :: std :: os :: raw :: c_void , tuples : * mut * const :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign pointer reference @ptr to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ptr\n Pointer to be assigned to value @v\n\n @return\n Value with pointer @ptr assigned to it"] pub fn metacall_value_from_ptr (v : * mut :: std :: os :: raw :: c_void , ptr : * const :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign future @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Future to be assigned to value @v\n\n @return\n Value with future @f assigned to it"] pub fn metacall_value_from_future (v : * mut :: std :: os :: raw :: c_void , f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign function @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Function to be assigned to value @v\n\n @return\n Value with function @f assigned to it"] pub fn metacall_value_from_function (v : * mut :: std :: os :: raw :: c_void , f : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign null to value @v\n\n @param[in] v\n Reference to the value\n\n @return\n Value with null assigned to it"] pub fn metacall_value_from_null (v : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign class @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Class to be assigned to value @v\n\n @return\n Value with class @c assigned to it"] pub fn metacall_value_from_class (v : * mut :: std :: os :: raw :: c_void , c : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign object @o to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] o\n Object to be assigned to value @v\n\n @return\n Value with object @o assigned to it"] pub fn metacall_value_from_object (v : * mut :: std :: os :: raw :: c_void , o : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign exception @ex to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ex\n Exception to be assigned to value @v\n\n @return\n Value with exception @ex assigned to it"] pub fn metacall_value_from_exception (v : * mut :: std :: os :: raw :: c_void , ex : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Assign throwable @th to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] th\n Throwable to be assigned to value @v\n\n @return\n Value with throwable @th assigned to it"] pub fn metacall_value_from_throwable (v : * mut :: std :: os :: raw :: c_void , th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Casts a value to a new type @id\n\n @param[in] v\n Reference to the value\n\n @param[in] id\n New type id of value to be casted\n\n @return\n Casted value or reference to @v if casting is between equivalent types"] pub fn metacall_value_cast (v : * mut :: std :: os :: raw :: c_void , id : metacall_value_id) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to boolean\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to boolean"] pub fn metacall_value_cast_bool (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_uchar ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to char\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to char"] pub fn metacall_value_cast_char (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to short\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to short"] pub fn metacall_value_cast_short (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_short ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to int\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to int"] pub fn metacall_value_cast_int (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to long\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to long"] pub fn metacall_value_cast_long (v : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_long ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to float\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to float"] pub fn metacall_value_cast_float (v : * mut * mut :: std :: os :: raw :: c_void) -> f32 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to double\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to double"] pub fn metacall_value_cast_double (v : * mut * mut :: std :: os :: raw :: c_void) -> f64 ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to string\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to a C string (null terminated)"] pub fn metacall_value_cast_string (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to buffer\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to buffer"] pub fn metacall_value_cast_buffer (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to array\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to array of values"] pub fn metacall_value_cast_array (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to map\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to map"] pub fn metacall_value_cast_map (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to ptr\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to ptr"] pub fn metacall_value_cast_ptr (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to future\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to future"] pub fn metacall_value_cast_future (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to function\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to function"] pub fn metacall_value_cast_function (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to null\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to null"] pub fn metacall_value_cast_null (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to class\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to class"] pub fn metacall_value_cast_class (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to object\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to object"] pub fn metacall_value_cast_object (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to exception\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to exception"] pub fn metacall_value_cast_exception (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert value @v implicitly to throwable\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to throwable"] pub fn metacall_value_cast_throwable (v : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Destroy a value from scope stack\n\n @param[in] v\n Reference to the value"] pub fn metacall_value_destroy (v : * mut :: std :: os :: raw :: c_void) ; } pub type metacall_pid = pid_t ; pub type metacall_pre_fork_callback_ptr = :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int > ; pub type metacall_post_fork_callback_ptr = :: std :: option :: Option < unsafe extern "C" fn (arg1 : metacall_pid , arg2 : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int > ; unsafe extern "C" { # [doc = " @brief\n Initialize fork detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_fork_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Set fork hook callback\n\n @param[in] pre_callback\n Callback to be called before fork detour is executed\n\n @param[in] post_callback\n Callback to be called after fork detour is executed"] pub fn metacall_fork (pre_callback : metacall_pre_fork_callback_ptr , post_callback : metacall_post_fork_callback_ptr) ; } unsafe extern "C" { # [doc = " @brief\n Unregister fork detours and destroy shared memory"] pub fn metacall_fork_destroy () ; } # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_initialize_configuration_type { pub tag : * const :: std :: os :: raw :: c_char , pub options : * mut :: std :: os :: raw :: c_void , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_initialize_configuration_type"] [:: std :: mem :: size_of :: < metacall_initialize_configuration_type > () - 16usize] ; ["Alignment of metacall_initialize_configuration_type"] [:: std :: mem :: align_of :: < metacall_initialize_configuration_type > () - 8usize] ; ["Offset of field: metacall_initialize_configuration_type::tag"] [:: std :: mem :: offset_of ! (metacall_initialize_configuration_type , tag) - 0usize] ; ["Offset of field: metacall_initialize_configuration_type::options"] [:: std :: mem :: offset_of ! (metacall_initialize_configuration_type , options) - 8usize] ; } ; pub type metacall_await_callback = :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > ; # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_await_callbacks_type { pub resolve : metacall_await_callback , pub reject : metacall_await_callback , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_await_callbacks_type"] [:: std :: mem :: size_of :: < metacall_await_callbacks_type > () - 16usize] ; ["Alignment of metacall_await_callbacks_type"] [:: std :: mem :: align_of :: < metacall_await_callbacks_type > () - 8usize] ; ["Offset of field: metacall_await_callbacks_type::resolve"] [:: std :: mem :: offset_of ! (metacall_await_callbacks_type , resolve) - 0usize] ; ["Offset of field: metacall_await_callbacks_type::reject"] [:: std :: mem :: offset_of ! (metacall_await_callbacks_type , reject) - 8usize] ; } ; pub type metacall_await_callbacks = metacall_await_callbacks_type ; # [repr (C)] # [derive (Debug , Copy , Clone)] pub struct metacall_version_type { pub major : :: std :: os :: raw :: c_uint , pub minor : :: std :: os :: raw :: c_uint , pub patch : :: std :: os :: raw :: c_uint , pub revision : * const :: std :: os :: raw :: c_char , pub str_ : * const :: std :: os :: raw :: c_char , pub name : * const :: std :: os :: raw :: c_char , } # [allow (clippy :: unnecessary_operation , clippy :: identity_op)] const _ : () = { ["Size of metacall_version_type"] [:: std :: mem :: size_of :: < metacall_version_type > () - 40usize] ; ["Alignment of metacall_version_type"] [:: std :: mem :: align_of :: < metacall_version_type > () - 8usize] ; ["Offset of field: metacall_version_type::major"] [:: std :: mem :: offset_of ! (metacall_version_type , major) - 0usize] ; ["Offset of field: metacall_version_type::minor"] [:: std :: mem :: offset_of ! (metacall_version_type , minor) - 4usize] ; ["Offset of field: metacall_version_type::patch"] [:: std :: mem :: offset_of ! (metacall_version_type , patch) - 8usize] ; ["Offset of field: metacall_version_type::revision"] [:: std :: mem :: offset_of ! (metacall_version_type , revision) - 16usize] ; ["Offset of field: metacall_version_type::str_"] [:: std :: mem :: offset_of ! (metacall_version_type , str_) - 24usize] ; ["Offset of field: metacall_version_type::name"] [:: std :: mem :: offset_of ! (metacall_version_type , name) - 32usize] ; } ; unsafe extern "C" { # [doc = " @brief\n Returns default serializer used by MetaCall\n\n @return\n Name of the serializer to be used with serialization methods"] pub fn metacall_serial () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Returns default detour used by MetaCall\n\n @return\n Name of the detour to be used with detouring methods"] pub fn metacall_detour () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Disables MetaCall logs, must be called before @metacall_initialize.\n\n When initializing MetaCall, it initializes a default logs to stdout\n if none was defined. If you want to benchmark or simply disable this\n default logs, you can call to this function before @metacall_initialize."] pub fn metacall_log_null () ; } unsafe extern "C" { # [doc = " @brief\n Flags to be set in MetaCall library\n\n @param[in] flags\n Combination of flags referring to definitions METACALL_FLAGS_*"] pub fn metacall_flags (flags : :: std :: os :: raw :: c_int) ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall library\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_initialize () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall library with configuration arguments\n\n @param[in] initialize_config\n Extension of the script to be loaded in memory with data to be injected\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_initialize_ex (initialize_config : * mut metacall_initialize_configuration_type) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Initialize MetaCall application arguments\n\n @param[in] argc\n Number of additional parameters to be passed to the runtime when initializing\n\n @param[in] argv\n Additional parameters to be passed to the runtime when initializing (when using MetaCall as an application)"] pub fn metacall_initialize_args (argc : :: std :: os :: raw :: c_int , argv : * mut * mut :: std :: os :: raw :: c_char) ; } unsafe extern "C" { # [doc = " @brief\n Get the number of arguments in which MetaCall was initialized\n\n @return\n An integer equal or greater than zero"] pub fn metacall_argc () -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the arguments in which MetaCall was initialized\n\n @return\n A pointer to an array of strings with the additional arguments"] pub fn metacall_argv () -> * mut * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Check if script context is loaded by @tag\n\n @param[in] tag\n Extension of the script (if tag is NULL, it returns the status of the whole MetaCall instance)\n\n @return\n Zero if context is initialized, different from zero otherwise"] pub fn metacall_is_initialized (tag : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Amount of function call arguments supported by MetaCall\n\n @return\n Number of arguments suported"] pub fn metacall_args_size () -> usize ; } unsafe extern "C" { # [doc = " @brief\n Set a execution path defined by @path to the extension script @tag\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path to be loaded\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_execution_path (tag : * const :: std :: os :: raw :: c_char , path : * const :: std :: os :: raw :: c_char) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Set a execution path defined by @path to the extension script @tag with length\n\n @param[in] tag\n Extension of the script\n\n @param[in] tag_length\n Length of the extension of the tag\n\n @param[in] path\n Path to be loaded\n\n @param[in] path_length\n Length of the path\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_execution_path_s (tag : * const :: std :: os :: raw :: c_char , tag_length : usize , path : * const :: std :: os :: raw :: c_char , path_length : usize) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a script from file specified by @path\n\n @param[in] tag\n Extension of the script\n\n @param[in] paths\n Path array of files\n\n @param[in] size\n Size of the array @paths\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_file (tag : * const :: std :: os :: raw :: c_char , paths : * mut * const :: std :: os :: raw :: c_char , size : usize , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a script from memory\n\n @param[in] tag\n Extension of the script\n\n @param[in] buffer\n Memory block representing the string of the script\n\n @param[in] size\n Memory block representing the string of the script\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_memory (tag : * const :: std :: os :: raw :: c_char , buffer : * const :: std :: os :: raw :: c_char , size : usize , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a package of scrips from file specified by @path into loader defined by @extension\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path of the package\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_package (tag : * const :: std :: os :: raw :: c_char , path : * const :: std :: os :: raw :: c_char , handle : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Loads a a list of scrips from configuration specified by @path into loader\n with the following format:\n {\n \"language_id\": \"<tag>\",\n \"path\": \"<path>\",\n \"scripts\": [ \"<script0>\", \"<script1>\", ..., \"<scriptN>\" ]\n }\n\n @param[in] path\n Path of the configuration\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @param[in] allocator\n Pointer to allocator will allocate the configuration\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_load_from_configuration (path : * const :: std :: os :: raw :: c_char , handle : * mut * mut :: std :: os :: raw :: c_void , allocator : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_s (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallhv (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n Includes @size in order to allow variadic arguments or safe calls\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallhv_s (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall (name : * const :: std :: os :: raw :: c_char , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt (name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_s (name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , size : usize , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallht_s (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ids : * const metacall_value_id , size : usize , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the function by @name\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] pub fn metacall_function (name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create an empty handler into a loader with name @name\n\n @param[in] loader\n Pointer to the loader which the handle belongs to\n\n @param[in] name\n Name of the handle\n\n @param[out] handle_ptr\n On success, returns the pointer to the handle created, otherwise NULL\n\n @return\n Return zero on success, different from zero on error"] pub fn metacall_handle_initialize (loader : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , handle_ptr : * mut * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Populate the objects of @handle_src into @handle_dest\n\n @param[inout] handle_dest\n Handle where the objects from @handle_src will be stored\n\n @param[in] handle_src\n Handle from where the objects will be copied\n\n @return\n Return zero on success, different from zero on error"] pub fn metacall_handle_populate (handle_dest : * mut :: std :: os :: raw :: c_void , handle_src : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the function by @name from @handle\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] pub fn metacall_handle_function (handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the function parameter type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n @param[in] parameter\n The index of the parameter to be retrieved\n\n @param[out] id\n The parameter type id that will be returned\n\n @return\n Return 0 if the @parameter index exists and @func is valid, 1 otherwhise"] pub fn metacall_function_parameter_type (func : * mut :: std :: os :: raw :: c_void , parameter : usize , id : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the function return type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n\n @param[out] id\n The value id of the return type of the function @func\n\n @return\n Return 0 if the @func is valid, 1 otherwhise"] pub fn metacall_function_return_type (func : * mut :: std :: os :: raw :: c_void , id : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get minimun mumber of arguments accepted by function @func\n\n @param[in] func\n Function reference\n\n @return\n Return mumber of arguments"] pub fn metacall_function_size (func : * mut :: std :: os :: raw :: c_void) -> usize ; } unsafe extern "C" { # [doc = " @brief\n Check if the function @func is asynchronous or synchronous\n\n @param[in] func\n Function reference\n\n @return\n Return 0 if it is syncrhonous, 1 if it is asynchronous and -1 if the function is NULL"] pub fn metacall_function_async (func : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the handle by @name\n\n @param[in] tag\n Extension of the script\n\n @param[in] name\n Name of the handle\n\n @return\n Handle reference, null if the function does not exist"] pub fn metacall_handle (tag : * const :: std :: os :: raw :: c_char , name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get name of a @handle\n\n @param[in] handle\n Pointer to the handle to be retrieved\n\n @return\n String that references the handle"] pub fn metacall_handle_id (handle : * mut :: std :: os :: raw :: c_void) -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Return a value representing the handle as a map of functions (or values)\n\n @param[in] handle\n Reference to the handle to be described\n\n @return\n A value of type map on success, null otherwise"] pub fn metacall_handle_export (handle : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfv (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of function arguments\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfv_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by variable arguments @va_args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallf (func : * mut :: std :: os :: raw :: c_void , ...) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfs (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfmv (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallfms (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @va_args\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] va_args\n Varidic function parameter types\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall_register (name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , func : * mut * mut :: std :: os :: raw :: c_void , return_type : metacall_value_id , size : usize , ...) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Pointer to value containing the result of the call"] pub fn metacall_registerv (name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , func : * mut * mut :: std :: os :: raw :: c_void , return_type : metacall_value_id , size : usize , types : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Obtain the loader instance by @tag\n\n @param[in] tag\n Tag in which the loader is identified, normally it is the extension of the script\n\n @return\n Pointer the loader by @tag"] pub fn metacall_loader (tag : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] loader\n Opaque pointer to the loader in which you want to register the function (this allows to register the function into a different loader than the host)\n\n @param[in] handle\n Opaque pointer to the handle in which you want to register the function (if it is NULL, it will be defined on the global scope of the loader)\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Zero if the function was registered properly, distinct from zero otherwise"] pub fn metacall_register_loaderv (loader : * mut :: std :: os :: raw :: c_void , handle : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , invoke : :: std :: option :: Option < unsafe extern "C" fn (arg1 : usize , arg2 : * mut * mut :: std :: os :: raw :: c_void , arg3 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , return_type : metacall_value_id , size : usize , types : * mut metacall_value_id) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Awaits for a promise and registers a callback to be executed when a future is resolved\n\n @param[in] f\n The pointer to the future\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await_future (f : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacall_await_s (name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func (offered without function pointers for languages without support to function pointers)\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] cb\n Pointer to struct containing the function pointers to reject and resolve that will be executed when task completion or error\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfv_await_struct_s (func : * mut :: std :: os :: raw :: c_void , args : * mut * mut :: std :: os :: raw :: c_void , size : usize , cb : metacall_await_callbacks , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] size\n Number of elements of the arrays @keys and @values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfmv_await (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfmv_await_s (func : * mut :: std :: os :: raw :: c_void , keys : * mut * mut :: std :: os :: raw :: c_void , values : * mut * mut :: std :: os :: raw :: c_void , size : usize , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfs_await (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] pub fn metacallfms_await (func : * mut :: std :: os :: raw :: c_void , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void , resolve_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , reject_callback : :: std :: option :: Option < unsafe extern "C" fn (arg1 : * mut :: std :: os :: raw :: c_void , arg2 : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void > , data : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the class by @name\n\n @param[in] name\n Name of the class\n\n @return\n Class reference, null if the class does not exist"] pub fn metacall_class (name : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a class method anonymously by value array @args (this procedure assumes there's no overloaded methods and does type conversion on values)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_class (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a class method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_class (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ret : metacall_value_id , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Create a new object instance from @cls by value array @args\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the new object\n\n @param[in] args\n Array of pointers constructor parameters\n\n @param[in] size\n Number of elements of constructor parameters\n\n @return\n Pointer to the new object value instance"] pub fn metacall_class_new (cls : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get an attribute from @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the class attribute value or NULL if an error occurred"] pub fn metacall_class_static_get (cls : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Set an attribute to @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] pub fn metacall_class_static_set (cls : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Call an object method anonymously by value array @args\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallv_object (obj : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Call a object method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] pub fn metacallt_object (obj : * mut :: std :: os :: raw :: c_void , name : * const :: std :: os :: raw :: c_char , ret : metacall_value_id , args : * mut * mut :: std :: os :: raw :: c_void , size : usize) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get an attribute from @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the object attribute value or NULL if an error occurred"] pub fn metacall_object_get (obj : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Set an attribute to @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] pub fn metacall_object_set (obj : * mut :: std :: os :: raw :: c_void , key : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the value contained by throwable object @th\n\n @param[in] th\n Pointer to the throwable object\n\n @return\n Pointer to the value inside of the throwable or NULL in case of error"] pub fn metacall_throwable_value (th : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Provide information about all loaded objects\n\n @param[out] size\n Size in bytes of return buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n String containing introspection information"] pub fn metacall_inspect (size : * mut usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide information about all loaded objects as a value\n\n @return\n Value containing introspection information"] pub fn metacall_inspect_value () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Convert the value @v to serialized string\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] v\n Reference to the value\n\n @param[out] size\n Size of new allocated string\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n New allocated string containing stringified value"] pub fn metacall_serialize (name : * const :: std :: os :: raw :: c_char , v : * mut :: std :: os :: raw :: c_void , size : * mut usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Convert the string @buffer to value\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] buffer\n String to be deserialized\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n New allocated value representing the string (must be freed)"] pub fn metacall_deserialize (name : * const :: std :: os :: raw :: c_char , buffer : * const :: std :: os :: raw :: c_char , size : usize , allocator : * mut :: std :: os :: raw :: c_void) -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Clear handle from memory and unload related resources\n\n @param[in] handle\n Reference to the handle to be unloaded\n\n @return\n Zero if success, different from zero otherwise"] pub fn metacall_clear (handle : * mut :: std :: os :: raw :: c_void) -> :: std :: os :: raw :: c_int ; } unsafe extern "C" { # [doc = " @brief\n Get the plugin extension handle to be used for loading plugins\n\n @return\n Pointer to the extension handle, or null if it failed to load"] pub fn metacall_plugin_extension () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the handle containing all the functionality of the plugins from core\n\n @return\n Pointer to the core plugin handle, or null if it failed to load"] pub fn metacall_plugin_core () -> * mut :: std :: os :: raw :: c_void ; } unsafe extern "C" { # [doc = " @brief\n Get the plugin extension path to be used for accessing the plugins folder\n\n @return\n String containing the core plugin path, or null if it failed to load the plugin extension"] pub fn metacall_plugin_path () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Destroy MetaCall library"] pub fn metacall_destroy () ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version struct\n\n @return\n Static struct containing unpacked version"] pub fn metacall_version () -> * const metacall_version_type ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is @major,\n I is @minor and P is @patch\n\n @param[in] major\n Unsigned integer representing major version\n\n @param[in] minor\n Unsigned integer representing minor version\n\n @param[in] patch\n Unsigned integer representing patch version\n\n @return\n Hexadecimal integer containing packed version"] pub fn metacall_version_hex_make (major : :: std :: os :: raw :: c_uint , minor : :: std :: os :: raw :: c_uint , patch : :: std :: os :: raw :: c_uint) -> u32 ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is major,\n I is minor and P is patch\n\n @return\n Hexadecimal integer containing packed version"] pub fn metacall_version_hex () -> u32 ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version string\n\n @return\n Static string containing module version"] pub fn metacall_version_str () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version revision string\n\n @return\n Static string containing module version revision"] pub fn metacall_version_revision () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module version name\n\n @return\n Static string containing module version name"] pub fn metacall_version_name () -> * const :: std :: os :: raw :: c_char ; } unsafe extern "C" { # [doc = " @brief\n Provide the module information\n\n @return\n Static string containing module information"] pub fn metacall_print_info () -> * const :: std :: os :: raw :: c_char ; } \ No newline at end of file +pub type __pid_t = ::std::os::raw::c_int; +pub type pid_t = __pid_t; +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum metacall_allocator_id { + METACALL_ALLOCATOR_STD = 0, + METACALL_ALLOCATOR_NGINX = 1, +} +unsafe extern "C" { + #[doc = " @brief\n Create an allocator instance\n\n @param[in] allocator_id\n Type of allocator to be created\n\n @param[in] ctx\n Context of the allocator\n\n @return\n Pointer to allocator if success, null otherwise"] + pub fn metacall_allocator_create( + allocator_id: metacall_allocator_id, + ctx: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Reserve memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] size\n Size in bytes to be allocated\n\n @return\n Pointer to allocated data on success, null otherwise"] + pub fn metacall_allocator_alloc( + allocator: *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Reallocate memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Original pointer to data\n\n @param[in] size\n Original size in bytes\n\n @param[in] new_size\n New size in bytes to be reallocated\n\n @return\n Pointer to new reallocated data on success, null otherwise"] + pub fn metacall_allocator_realloc( + allocator: *mut ::std::os::raw::c_void, + data: *mut ::std::os::raw::c_void, + size: usize, + new_size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Free memory from an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance\n\n @param[in] data\n Pointer to data to be freed"] + pub fn metacall_allocator_free( + allocator: *mut ::std::os::raw::c_void, + data: *mut ::std::os::raw::c_void, + ); +} +unsafe extern "C" { + #[doc = " @brief\n Destroy an allocator instance\n\n @param[in] allocator\n Pointer to allocator instance"] + pub fn metacall_allocator_destroy(allocator: *mut ::std::os::raw::c_void); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct metacall_exception_type { + pub message: *const ::std::os::raw::c_char, + pub label: *const ::std::os::raw::c_char, + pub code: i64, + pub stacktrace: *const ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of metacall_exception_type"][::std::mem::size_of::<metacall_exception_type>() - 32usize]; + ["Alignment of metacall_exception_type"] + [::std::mem::align_of::<metacall_exception_type>() - 8usize]; + ["Offset of field: metacall_exception_type::message"] + [::std::mem::offset_of!(metacall_exception_type, message) - 0usize]; + ["Offset of field: metacall_exception_type::label"] + [::std::mem::offset_of!(metacall_exception_type, label) - 8usize]; + ["Offset of field: metacall_exception_type::code"] + [::std::mem::offset_of!(metacall_exception_type, code) - 16usize]; + ["Offset of field: metacall_exception_type::stacktrace"] + [::std::mem::offset_of!(metacall_exception_type, stacktrace) - 24usize]; +}; +pub type metacall_exception = *mut metacall_exception_type; +unsafe extern "C" { + #[doc = " @brief\n Create an throwable value from an exception with a simple API in a single instruction\n\n @param[in] label\n Label of the exception\n\n @param[in] code\n Error code of the exception\n\n @param[in] stacktrace\n Stack trace of the exception\n\n @param[in] message\n Message of the exception to be formatted with the variable arguments\n\n @param[in] va_args\n Arguments for formatting the message\n\n @return\n The value of type throwable containing the exception created"] + pub fn metacall_error_throw( + label: *const ::std::os::raw::c_char, + code: i64, + stacktrace: *const ::std::os::raw::c_char, + message: *const ::std::os::raw::c_char, + ... + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Retrieve the exception from a value, it can be either a throwable value with an exception inside or an exception itself\n\n @param[in] v\n Value that represents the exception to be retrieved\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to @v\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_error_from_value( + v: *mut ::std::os::raw::c_void, + ex: metacall_exception, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Retrieve last error that has happened after a call to any API from MetaCall\n\n @param[out] ex\n Exception that will be used as out parameter, the lifetime of the struct fields is attached to the internal MetaCall exception\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_error_last(ex: metacall_exception) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Clear last error that has happened after a call to any API from MetaCall"] + pub fn metacall_error_clear(); +} +unsafe extern "C" { + #[doc = " @brief\n Initialize link detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_link_initialize() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_link_register( + tag: *const ::std::os::raw::c_char, + library: *const ::std::os::raw::c_char, + symbol: *const ::std::os::raw::c_char, + fn_: ::std::option::Option<unsafe extern "C" fn()>, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Register a function pointer in order to allow function\n interposition when loading a library, if you register a\n function @symbol called 'foo', when you try to dlsym (or the equivalent\n on every platform), you will get the pointer to @fn, even if\n the symbol does not exist in the library, it will work.\n Function interposition is required in order to hook into runtimes\n and dynamically interpose our functions.\n\n @param[in] loader\n Pointer to the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @param[in] fn\n Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_link_register_loader( + loader: *mut ::std::os::raw::c_void, + library: *const ::std::os::raw::c_char, + symbol: *const ::std::os::raw::c_char, + fn_: ::std::option::Option<unsafe extern "C" fn()>, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Remove the hook previously registered\n\n @param[in] tag\n Name of the loader which the @library belongs to\n\n @param[in] library\n Name of the library that is going to be hooked\n\n @param[in] symbol\n Name of the function to be interposed\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_link_unregister( + tag: *const ::std::os::raw::c_char, + library: *const ::std::os::raw::c_char, + symbol: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Unregister link detours and destroy shared memory"] + pub fn metacall_link_destroy(); +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum metacall_log_id { + METACALL_LOG_STDIO = 0, + METACALL_LOG_FILE = 1, + METACALL_LOG_SOCKET = 2, + METACALL_LOG_SYSLOG = 3, + METACALL_LOG_NGINX = 4, + METACALL_LOG_CUSTOM = 5, +} +unsafe extern "C" { + #[doc = " @brief\n Create a log instance\n\n @param[in] log_id\n Type of log to be created\n\n @param[in] ctx\n Context of the log (a pointer to metacall_log_{stdio, file, socket, syslog, nginx, custom}_type)\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_log( + log_id: metacall_log_id, + ctx: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum metacall_value_id { + METACALL_BOOL = 0, + METACALL_CHAR = 1, + METACALL_SHORT = 2, + METACALL_INT = 3, + METACALL_LONG = 4, + METACALL_FLOAT = 5, + METACALL_DOUBLE = 6, + METACALL_STRING = 7, + METACALL_BUFFER = 8, + METACALL_ARRAY = 9, + METACALL_MAP = 10, + METACALL_PTR = 11, + METACALL_FUTURE = 12, + METACALL_FUNCTION = 13, + METACALL_NULL = 14, + METACALL_CLASS = 15, + METACALL_OBJECT = 16, + METACALL_EXCEPTION = 17, + METACALL_THROWABLE = 18, + METACALL_SIZE = 19, + METACALL_INVALID = 20, +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from boolean @b\n\n @param[in] b\n Boolean will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_bool(b: ::std::os::raw::c_uchar) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from char @c\n\n @param[in] c\n Character will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_char(c: ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from short @s\n\n @param[in] s\n Short will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_short(s: ::std::os::raw::c_short) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from integer @i\n\n @param[in] i\n Integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_int(i: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from long @l\n\n @param[in] l\n Long integer will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_long(l: ::std::os::raw::c_long) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from single precision floating point number @f\n\n @param[in] f\n Float will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_float(f: f32) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from double precision floating point number @d\n\n @param[in] d\n Double will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_double(d: f64) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from a C string @str\n\n @param[in] str\n Constant string will be copied into value (needs to be null terminated)\n\n @param[in] length\n Length of the constant string\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_string( + str_: *const ::std::os::raw::c_char, + length: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value buffer from array @buffer\n\n @param[in] buffer\n Constant memory block will be copied into value array\n\n @param[in] size\n Size in bytes of data contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_buffer( + buffer: *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value array from array of values @values\n\n @param[in] values\n Constant array of values will be copied into value list\n\n @param[in] size\n Number of elements contained in the array\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_array( + values: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value map from array of tuples @map\n\n @param[in] tuples\n Constant array of tuples will be copied into value map\n\n @param[in] size\n Number of elements contained in the map\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_map( + tuples: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from pointer @ptr\n\n @param[in] ptr\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_ptr( + ptr: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from future @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_future( + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from function @f\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_function( + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from function @f binding a closure @c to it\n\n @param[in] f\n Pointer to constant data will be copied into value\n\n @param[in] c\n Pointer to closure that will be binded into function @f\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_function_closure( + f: *mut ::std::os::raw::c_void, + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value of type null\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_null() -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from class @c\n\n @param[in] c\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_class( + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from object @o\n\n @param[in] o\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_object( + o: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from exception @ex\n\n @param[in] ex\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_exception( + ex: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a value from throwable @th\n\n @param[in] th\n Pointer to constant data will be copied into value\n\n @return\n Pointer to value if success, null otherwhise"] + pub fn metacall_value_create_throwable( + th: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Returns the size of the value\n\n @param[in] v\n Reference to the value\n\n @return\n Size in bytes of the value"] + pub fn metacall_value_size(v: *mut ::std::os::raw::c_void) -> usize; +} +unsafe extern "C" { + #[doc = " @brief\n Returns the amount of values this value contains\n\n @param[in] v\n Reference to the value\n\n @return\n Number of values @v represents"] + pub fn metacall_value_count(v: *mut ::std::os::raw::c_void) -> usize; +} +unsafe extern "C" { + #[doc = " @brief\n Provide type id of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return type id assigned to value"] + pub fn metacall_value_id(v: *mut ::std::os::raw::c_void) -> metacall_value_id; +} +unsafe extern "C" { + #[doc = " @brief\n Provide type id in a readable form (as string) of a type id\n\n @param[in] id\n Value type identifier\n\n @return\n Return string related to the type id"] + pub fn metacall_value_id_name(id: metacall_value_id) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Provide type id in a readable form (as string) of value\n\n @param[in] v\n Reference to the value\n\n @return\n Return string related to the type id assigned to value"] + pub fn metacall_value_type_name( + v: *mut ::std::os::raw::c_void, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Deep copies the value @v, the result copy resets\n the reference counter and ownership, including the finalizer\n\n @param[in] v\n Reference to the value to be copied\n\n @return\n Copy of the value @v on success, null otherwhise"] + pub fn metacall_value_copy(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Creates a new pointer value, with a reference to the\n data contained inside the value @v. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n\n In this case, void *ptr is a value equivalent to int*,\n and it points directly to the integer contained in void *v.\n Note that if we destroy the value @v, the reference will\n point to already freed memory, causing use-after-free when used.\n\n @param[in] v\n Reference to the value to be referenced\n\n @return\n A new value of type pointer, pointing to the @v data"] + pub fn metacall_value_reference(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n If you pass a reference previously created (i.e a value of\n type pointer, pointing to another value), it returns the\n original value. It does not modify the memory of the values\n neither allocates anything. If the value @v is pointing to\n has been deleted, it will cause an use-after-free. For example:\n\n void *v = metacall_value_create_int(20);\n void *ptr = metacall_value_reference(v);\n void *w = metacall_value_dereference(ptr);\n assert(v == w); // Both are the same value\n\n @param[in] v\n Reference to the value to be dereferenced\n\n @return\n The value containing the data which ptr is pointing to"] + pub fn metacall_value_dereference( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Copies the ownership from @src to @dst, including the finalizer,\n and resets the owner and finalizer of @src\n\n @param[in] src\n Source value which will lose the ownership\n\n @param[in] dst\n Destination value which will recieve the ownership"] + pub fn metacall_value_move(src: *mut ::std::os::raw::c_void, dest: *mut ::std::os::raw::c_void); +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to boolean\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to boolean"] + pub fn metacall_value_to_bool(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_uchar; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to char\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to char"] + pub fn metacall_value_to_char(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to short\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to short"] + pub fn metacall_value_to_short(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_short; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to integer"] + pub fn metacall_value_to_int(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to long integer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to long integer"] + pub fn metacall_value_to_long(v: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to single precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to float"] + pub fn metacall_value_to_float(v: *mut ::std::os::raw::c_void) -> f32; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to double precision floating point\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to dobule"] + pub fn metacall_value_to_double(v: *mut ::std::os::raw::c_void) -> f64; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to string\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to C string (null terminated)"] + pub fn metacall_value_to_string(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to buffer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to memory block"] + pub fn metacall_value_to_buffer(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to array of values\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to array of values"] + pub fn metacall_value_to_array( + v: *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to map\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to map (array of tuples (array of values))"] + pub fn metacall_value_to_map( + v: *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to pointer\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to pointer"] + pub fn metacall_value_to_ptr(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to future\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to future"] + pub fn metacall_value_to_future(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to function\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to function"] + pub fn metacall_value_to_function( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to null\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to null"] + pub fn metacall_value_to_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to class\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to class"] + pub fn metacall_value_to_class(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to object\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to object"] + pub fn metacall_value_to_object(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to exception\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to exception"] + pub fn metacall_value_to_exception( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v to throwable\n\n @param[in] v\n Reference to the value\n\n @return\n Value converted to throwable"] + pub fn metacall_value_to_throwable( + v: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign boolean @b to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] b\n Boolean to be assigned to value @v\n\n @return\n Value with boolean @b assigned to it"] + pub fn metacall_value_from_bool( + v: *mut ::std::os::raw::c_void, + b: ::std::os::raw::c_uchar, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign character @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Character to be assigned to value @v\n\n @return\n Value with char @c assigned to it"] + pub fn metacall_value_from_char( + v: *mut ::std::os::raw::c_void, + c: ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign short @s to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] s\n Short to be assigned to value @v\n\n @return\n Value with short @s assigned to it"] + pub fn metacall_value_from_short( + v: *mut ::std::os::raw::c_void, + s: ::std::os::raw::c_short, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign integer @i to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] i\n Integer to be assigned to value @v\n\n @return\n Value with integer @i assigned to it"] + pub fn metacall_value_from_int( + v: *mut ::std::os::raw::c_void, + i: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign long integer @l to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] l\n Long integer to be assigned to value @v\n\n @return\n Value with long @l assigned to it"] + pub fn metacall_value_from_long( + v: *mut ::std::os::raw::c_void, + l: ::std::os::raw::c_long, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign single precision floating point @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Float to be assigned to value @v\n\n @return\n Value with float @f assigned to it"] + pub fn metacall_value_from_float( + v: *mut ::std::os::raw::c_void, + f: f32, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign double precision floating point @d to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] d\n Double to be assigned to value @v\n\n @return\n Value with double @d assigned to it"] + pub fn metacall_value_from_double( + v: *mut ::std::os::raw::c_void, + d: f64, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign string @str to value @v, truncates to @v size if it is smaller\n than @length + 1. It does not add null terminator if truncated.\n\n @param[in] v\n Reference to the value\n\n @param[in] str\n Constant string to be assigned to value @v (it needs to be null terminated)\n\n @param[in] length\n Length of the constant string @str\n\n @return\n Value with string @str assigned to it"] + pub fn metacall_value_from_string( + v: *mut ::std::os::raw::c_void, + str_: *const ::std::os::raw::c_char, + length: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign array @buffer to value buffer @v\n\n @param[in] v\n Reference to the value\n\n @param[in] buffer\n Constant array to be assigned to value @v\n\n @param[in] size\n Number of elements contained in @buffer\n\n @return\n Value with array @buffer assigned to it"] + pub fn metacall_value_from_buffer( + v: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign array of values @values to value array @v\n\n @param[in] v\n Reference to the value\n\n @param[in] values\n Constant array of values to be assigned to value array @v\n\n @param[in] size\n Number of values contained in constant array @values\n\n @return\n Value with array of values @values assigned to it"] + pub fn metacall_value_from_array( + v: *mut ::std::os::raw::c_void, + values: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign array of values @values to value map @v\n\n @param[in] v\n Reference to the value\n\n @param[in] tuples\n Constant array of tuples to be assigned to value map @v\n\n @param[in] size\n Number of values contained in constant array @tuples\n\n @return\n Value with array of tuples @tuples assigned to it"] + pub fn metacall_value_from_map( + v: *mut ::std::os::raw::c_void, + tuples: *mut *const ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign pointer reference @ptr to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ptr\n Pointer to be assigned to value @v\n\n @return\n Value with pointer @ptr assigned to it"] + pub fn metacall_value_from_ptr( + v: *mut ::std::os::raw::c_void, + ptr: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign future @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Future to be assigned to value @v\n\n @return\n Value with future @f assigned to it"] + pub fn metacall_value_from_future( + v: *mut ::std::os::raw::c_void, + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign function @f to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] f\n Function to be assigned to value @v\n\n @return\n Value with function @f assigned to it"] + pub fn metacall_value_from_function( + v: *mut ::std::os::raw::c_void, + f: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign null to value @v\n\n @param[in] v\n Reference to the value\n\n @return\n Value with null assigned to it"] + pub fn metacall_value_from_null(v: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign class @c to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] c\n Class to be assigned to value @v\n\n @return\n Value with class @c assigned to it"] + pub fn metacall_value_from_class( + v: *mut ::std::os::raw::c_void, + c: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign object @o to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] o\n Object to be assigned to value @v\n\n @return\n Value with object @o assigned to it"] + pub fn metacall_value_from_object( + v: *mut ::std::os::raw::c_void, + o: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign exception @ex to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] ex\n Exception to be assigned to value @v\n\n @return\n Value with exception @ex assigned to it"] + pub fn metacall_value_from_exception( + v: *mut ::std::os::raw::c_void, + ex: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Assign throwable @th to value @v\n\n @param[in] v\n Reference to the value\n\n @param[in] th\n Throwable to be assigned to value @v\n\n @return\n Value with throwable @th assigned to it"] + pub fn metacall_value_from_throwable( + v: *mut ::std::os::raw::c_void, + th: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Casts a value to a new type @id\n\n @param[in] v\n Reference to the value\n\n @param[in] id\n New type id of value to be casted\n\n @return\n Casted value or reference to @v if casting is between equivalent types"] + pub fn metacall_value_cast( + v: *mut ::std::os::raw::c_void, + id: metacall_value_id, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to boolean\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to boolean"] + pub fn metacall_value_cast_bool(v: *mut *mut ::std::os::raw::c_void) + -> ::std::os::raw::c_uchar; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to char\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to char"] + pub fn metacall_value_cast_char(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to short\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to short"] + pub fn metacall_value_cast_short( + v: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_short; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to int\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to int"] + pub fn metacall_value_cast_int(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to long\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to long"] + pub fn metacall_value_cast_long(v: *mut *mut ::std::os::raw::c_void) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to float\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to float"] + pub fn metacall_value_cast_float(v: *mut *mut ::std::os::raw::c_void) -> f32; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to double\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to double"] + pub fn metacall_value_cast_double(v: *mut *mut ::std::os::raw::c_void) -> f64; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to string\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to a C string (null terminated)"] + pub fn metacall_value_cast_string( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to buffer\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to buffer"] + pub fn metacall_value_cast_buffer( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to array\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to array of values"] + pub fn metacall_value_cast_array( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to map\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to map"] + pub fn metacall_value_cast_map( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to ptr\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to ptr"] + pub fn metacall_value_cast_ptr( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to future\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to future"] + pub fn metacall_value_cast_future( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to function\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to function"] + pub fn metacall_value_cast_function( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to null\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to null"] + pub fn metacall_value_cast_null( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to class\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to class"] + pub fn metacall_value_cast_class( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to object\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to object"] + pub fn metacall_value_cast_object( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to exception\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to exception"] + pub fn metacall_value_cast_exception( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert value @v implicitly to throwable\n\n @param[in] v\n Reference to the reference of the value\n\n @return\n Value converted to throwable"] + pub fn metacall_value_cast_throwable( + v: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Destroy a value from scope stack\n\n @param[in] v\n Reference to the value"] + pub fn metacall_value_destroy(v: *mut ::std::os::raw::c_void); +} +pub type metacall_pid = pid_t; +pub type metacall_pre_fork_callback_ptr = ::std::option::Option< + unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, +>; +pub type metacall_post_fork_callback_ptr = ::std::option::Option< + unsafe extern "C" fn( + arg1: metacall_pid, + arg2: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, +>; +unsafe extern "C" { + #[doc = " @brief\n Initialize fork detours and allocate shared memory\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_fork_initialize() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Set fork hook callback\n\n @param[in] pre_callback\n Callback to be called before fork detour is executed\n\n @param[in] post_callback\n Callback to be called after fork detour is executed"] + pub fn metacall_fork( + pre_callback: metacall_pre_fork_callback_ptr, + post_callback: metacall_post_fork_callback_ptr, + ); +} +unsafe extern "C" { + #[doc = " @brief\n Unregister fork detours and destroy shared memory"] + pub fn metacall_fork_destroy(); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct metacall_initialize_configuration_type { + pub tag: *const ::std::os::raw::c_char, + pub options: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of metacall_initialize_configuration_type"] + [::std::mem::size_of::<metacall_initialize_configuration_type>() - 16usize]; + ["Alignment of metacall_initialize_configuration_type"] + [::std::mem::align_of::<metacall_initialize_configuration_type>() - 8usize]; + ["Offset of field: metacall_initialize_configuration_type::tag"] + [::std::mem::offset_of!(metacall_initialize_configuration_type, tag) - 0usize]; + ["Offset of field: metacall_initialize_configuration_type::options"] + [::std::mem::offset_of!(metacall_initialize_configuration_type, options) - 8usize]; +}; +pub type metacall_await_callback = ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, +>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct metacall_await_callbacks_type { + pub resolve: metacall_await_callback, + pub reject: metacall_await_callback, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of metacall_await_callbacks_type"] + [::std::mem::size_of::<metacall_await_callbacks_type>() - 16usize]; + ["Alignment of metacall_await_callbacks_type"] + [::std::mem::align_of::<metacall_await_callbacks_type>() - 8usize]; + ["Offset of field: metacall_await_callbacks_type::resolve"] + [::std::mem::offset_of!(metacall_await_callbacks_type, resolve) - 0usize]; + ["Offset of field: metacall_await_callbacks_type::reject"] + [::std::mem::offset_of!(metacall_await_callbacks_type, reject) - 8usize]; +}; +pub type metacall_await_callbacks = metacall_await_callbacks_type; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct metacall_version_type { + pub major: ::std::os::raw::c_uint, + pub minor: ::std::os::raw::c_uint, + pub patch: ::std::os::raw::c_uint, + pub revision: *const ::std::os::raw::c_char, + pub str_: *const ::std::os::raw::c_char, + pub name: *const ::std::os::raw::c_char, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of metacall_version_type"][::std::mem::size_of::<metacall_version_type>() - 40usize]; + ["Alignment of metacall_version_type"] + [::std::mem::align_of::<metacall_version_type>() - 8usize]; + ["Offset of field: metacall_version_type::major"] + [::std::mem::offset_of!(metacall_version_type, major) - 0usize]; + ["Offset of field: metacall_version_type::minor"] + [::std::mem::offset_of!(metacall_version_type, minor) - 4usize]; + ["Offset of field: metacall_version_type::patch"] + [::std::mem::offset_of!(metacall_version_type, patch) - 8usize]; + ["Offset of field: metacall_version_type::revision"] + [::std::mem::offset_of!(metacall_version_type, revision) - 16usize]; + ["Offset of field: metacall_version_type::str_"] + [::std::mem::offset_of!(metacall_version_type, str_) - 24usize]; + ["Offset of field: metacall_version_type::name"] + [::std::mem::offset_of!(metacall_version_type, name) - 32usize]; +}; +unsafe extern "C" { + #[doc = " @brief\n Returns default serializer used by MetaCall\n\n @return\n Name of the serializer to be used with serialization methods"] + pub fn metacall_serial() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Returns default detour used by MetaCall\n\n @return\n Name of the detour to be used with detouring methods"] + pub fn metacall_detour() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Disables MetaCall logs, must be called before @metacall_initialize.\n\n When initializing MetaCall, it initializes a default logs to stdout\n if none was defined. If you want to benchmark or simply disable this\n default logs, you can call to this function before @metacall_initialize."] + pub fn metacall_log_null(); +} +unsafe extern "C" { + #[doc = " @brief\n Flags to be set in MetaCall library\n\n @param[in] flags\n Combination of flags referring to definitions METACALL_FLAGS_*"] + pub fn metacall_flags(flags: ::std::os::raw::c_int); +} +unsafe extern "C" { + #[doc = " @brief\n Initialize MetaCall library\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_initialize() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Initialize MetaCall library with configuration arguments\n\n @param[in] initialize_config\n Extension of the script to be loaded in memory with data to be injected\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_initialize_ex( + initialize_config: *mut metacall_initialize_configuration_type, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Initialize MetaCall application arguments\n\n @param[in] argc\n Number of additional parameters to be passed to the runtime when initializing\n\n @param[in] argv\n Additional parameters to be passed to the runtime when initializing (when using MetaCall as an application)"] + pub fn metacall_initialize_args( + argc: ::std::os::raw::c_int, + argv: *mut *mut ::std::os::raw::c_char, + ); +} +unsafe extern "C" { + #[doc = " @brief\n Get the number of arguments in which MetaCall was initialized\n\n @return\n An integer equal or greater than zero"] + pub fn metacall_argc() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the arguments in which MetaCall was initialized\n\n @return\n A pointer to an array of strings with the additional arguments"] + pub fn metacall_argv() -> *mut *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Check if script context is loaded by @tag\n\n @param[in] tag\n Extension of the script (if tag is NULL, it returns the status of the whole MetaCall instance)\n\n @return\n Zero if context is initialized, different from zero otherwise"] + pub fn metacall_is_initialized(tag: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Amount of function call arguments supported by MetaCall\n\n @return\n Number of arguments suported"] + pub fn metacall_args_size() -> usize; +} +unsafe extern "C" { + #[doc = " @brief\n Set a execution path defined by @path to the extension script @tag\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path to be loaded\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_execution_path( + tag: *const ::std::os::raw::c_char, + path: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Set a execution path defined by @path to the extension script @tag with length\n\n @param[in] tag\n Extension of the script\n\n @param[in] tag_length\n Length of the extension of the tag\n\n @param[in] path\n Path to be loaded\n\n @param[in] path_length\n Length of the path\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_execution_path_s( + tag: *const ::std::os::raw::c_char, + tag_length: usize, + path: *const ::std::os::raw::c_char, + path_length: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Loads a script from file specified by @path\n\n @param[in] tag\n Extension of the script\n\n @param[in] paths\n Path array of files\n\n @param[in] size\n Size of the array @paths\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_load_from_file( + tag: *const ::std::os::raw::c_char, + paths: *mut *const ::std::os::raw::c_char, + size: usize, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Loads a script from memory\n\n @param[in] tag\n Extension of the script\n\n @param[in] buffer\n Memory block representing the string of the script\n\n @param[in] size\n Memory block representing the string of the script\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_load_from_memory( + tag: *const ::std::os::raw::c_char, + buffer: *const ::std::os::raw::c_char, + size: usize, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Loads a package of scrips from file specified by @path into loader defined by @extension\n\n @param[in] tag\n Extension of the script\n\n @param[in] path\n Path of the package\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_load_from_package( + tag: *const ::std::os::raw::c_char, + path: *const ::std::os::raw::c_char, + handle: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Loads a a list of scrips from configuration specified by @path into loader\n with the following format:\n {\n \"language_id\": \"<tag>\",\n \"path\": \"<path>\",\n \"scripts\": [ \"<script0>\", \"<script1>\", ..., \"<scriptN>\" ]\n }\n\n @param[in] path\n Path of the configuration\n\n @param[inout] handle\n Optional pointer to reference of loaded handle. If the parameter is NULL, the symbols loaded are\n propagated to the loader scope (i.e they will share the scope between all previously loaded files and they can collide).\n Otherwise, if we pass a void* pointer set to NULL, it will behave as output parameter, obtaining the reference to the\n created handle, which can be later on used for calling to functions of that handle. The symbols will not be propagated\n to the loader scope and they will be private (this prevents collisions). The last case is if we pass an already allocated\n handle (i.e a void* pointer pointing to an previously loaded handle), then in this case, the symbols loaded will be propagated\n to the previously allocated handle, and it will behave as a in parameter.\n\n @param[in] allocator\n Pointer to allocator will allocate the configuration\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_load_from_configuration( + path: *const ::std::os::raw::c_char, + handle: *mut *mut ::std::os::raw::c_void, + allocator: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallv( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by value array @args\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallv_s( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallhv( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by handle @handle value array @args\n This function allows to avoid name collisions when calling functions by name\n Includes @size in order to allow variadic arguments or safe calls\n\n @param[in] handle\n Handle where the function belongs\n\n @param[in] name\n Name of the function\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of the call\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallhv_s( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacall(name: *const ::std::os::raw::c_char, ...) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallt( + name: *const ::std::os::raw::c_char, + ids: *const metacall_value_id, + ... + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallt_s( + name: *const ::std::os::raw::c_char, + ids: *const metacall_value_id, + size: usize, + ... + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by type array @ids and variable arguments @va_args\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @param[in] ids\n Array of types refered to @va_args\n\n @param[in] size\n Number of elements of the call\n\n @param[in] va_args\n Varidic function parameters\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallht_s( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ids: *const metacall_value_id, + size: usize, + ... + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get the function by @name\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] + pub fn metacall_function(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create an empty handler into a loader with name @name\n\n @param[in] loader\n Pointer to the loader which the handle belongs to\n\n @param[in] name\n Name of the handle\n\n @param[out] handle_ptr\n On success, returns the pointer to the handle created, otherwise NULL\n\n @return\n Return zero on success, different from zero on error"] + pub fn metacall_handle_initialize( + loader: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + handle_ptr: *mut *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Populate the objects of @handle_src into @handle_dest\n\n @param[inout] handle_dest\n Handle where the objects from @handle_src will be stored\n\n @param[in] handle_src\n Handle from where the objects will be copied\n\n @return\n Return zero on success, different from zero on error"] + pub fn metacall_handle_populate( + handle_dest: *mut ::std::os::raw::c_void, + handle_src: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the function by @name from @handle\n\n @param[in] handle\n Pointer to the handle returned by metacall_load_from_{file, memory, package}\n\n @param[in] name\n Name of the function\n\n @return\n Function reference, null if the function does not exist"] + pub fn metacall_handle_function( + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get the function parameter type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n @param[in] parameter\n The index of the parameter to be retrieved\n\n @param[out] id\n The parameter type id that will be returned\n\n @return\n Return 0 if the @parameter index exists and @func is valid, 1 otherwhise"] + pub fn metacall_function_parameter_type( + func: *mut ::std::os::raw::c_void, + parameter: usize, + id: *mut metacall_value_id, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the function return type id\n\n @param[in] func\n The pointer to the function obtained from metacall_function\n\n\n @param[out] id\n The value id of the return type of the function @func\n\n @return\n Return 0 if the @func is valid, 1 otherwhise"] + pub fn metacall_function_return_type( + func: *mut ::std::os::raw::c_void, + id: *mut metacall_value_id, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get minimun mumber of arguments accepted by function @func\n\n @param[in] func\n Function reference\n\n @return\n Return mumber of arguments"] + pub fn metacall_function_size(func: *mut ::std::os::raw::c_void) -> usize; +} +unsafe extern "C" { + #[doc = " @brief\n Check if the function @func is asynchronous or synchronous\n\n @param[in] func\n Function reference\n\n @return\n Return 0 if it is syncrhonous, 1 if it is asynchronous and -1 if the function is NULL"] + pub fn metacall_function_async(func: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the handle by @name\n\n @param[in] tag\n Extension of the script\n\n @param[in] name\n Name of the handle\n\n @return\n Handle reference, null if the function does not exist"] + pub fn metacall_handle( + tag: *const ::std::os::raw::c_char, + name: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get name of a @handle\n\n @param[in] handle\n Pointer to the handle to be retrieved\n\n @return\n String that references the handle"] + pub fn metacall_handle_id(handle: *mut ::std::os::raw::c_void) + -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Return a value representing the handle as a map of functions (or values)\n\n @param[in] handle\n Reference to the handle to be described\n\n @return\n A value of type map on success, null otherwise"] + pub fn metacall_handle_export( + handle: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallfv( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of function arguments\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallfv_s( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by variable arguments @va_args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallf(func: *mut ::std::os::raw::c_void, ...) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallfs( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallfmv( + func: *mut ::std::os::raw::c_void, + keys: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallfms( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Register a function by name @name and arguments @va_args\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] va_args\n Varidic function parameter types\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacall_register( + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + func: *mut *mut ::std::os::raw::c_void, + return_type: metacall_value_id, + size: usize, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[out] func\n Will set the pointer to the function if the parameter is not null\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacall_registerv( + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + func: *mut *mut ::std::os::raw::c_void, + return_type: metacall_value_id, + size: usize, + types: *mut metacall_value_id, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Obtain the loader instance by @tag\n\n @param[in] tag\n Tag in which the loader is identified, normally it is the extension of the script\n\n @return\n Pointer the loader by @tag"] + pub fn metacall_loader(tag: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Register a function by name @name and arguments @types\n\n @param[in] loader\n Opaque pointer to the loader in which you want to register the function (this allows to register the function into a different loader than the host)\n\n @param[in] handle\n Opaque pointer to the handle in which you want to register the function (if it is NULL, it will be defined on the global scope of the loader)\n\n @param[in] name\n Name of the function (if it is NULL, function is not registered into host scope)\n\n @param[in] invoke\n Pointer to function invoke interface (argc, argv, data)\n\n @param[in] return_type\n Type of return value\n\n @param[in] size\n Number of function arguments\n\n @param[in] types\n List of parameter types\n\n @return\n Zero if the function was registered properly, distinct from zero otherwise"] + pub fn metacall_register_loaderv( + loader: *mut ::std::os::raw::c_void, + handle: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + invoke: ::std::option::Option< + unsafe extern "C" fn( + arg1: usize, + arg2: *mut *mut ::std::os::raw::c_void, + arg3: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + return_type: metacall_value_id, + size: usize, + types: *mut metacall_value_id, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacall_await( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Awaits for a promise and registers a callback to be executed when a future is resolved\n\n @param[in] f\n The pointer to the future\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacall_await_future( + f: *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Executes an asynchronous call to the function and registers a callback to be executed when a future is resolved (it does block)\n\n @param[in] name\n The name of the function to be called asynchronously\n\n @param[in] args\n Array of pointers to the values to be passed to the function\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacall_await_s( + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfv_await( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfv_await_s( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by value array @args and function @func (offered without function pointers for languages without support to function pointers)\n\n @param[in] func\n Reference to function to be called\n\n @param[in] args\n Array of pointers to values\n\n @param[in] size\n Number of elements of the array @args\n\n @param[in] cb\n Pointer to struct containing the function pointers to reject and resolve that will be executed when task completion or error\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfv_await_struct_s( + func: *mut ::std::os::raw::c_void, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + cb: metacall_await_callbacks, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] size\n Number of elements of the arrays @keys and @values\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfmv_await( + func: *mut ::std::os::raw::c_void, + keys: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by value map (@keys -> @values) and function @func\n\n @param[in] func\n Reference to function to be called\n\n @param[in] keys\n Array of values representing argument keys\n\n @param[in] values\n Array of values representing argument values data\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfmv_await_s( + func: *mut ::std::os::raw::c_void, + keys: *mut *mut ::std::os::raw::c_void, + values: *mut *mut ::std::os::raw::c_void, + size: usize, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing an array to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfs_await( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call an asynchronous function anonymously by function @func and serial @buffer of size @size\n\n @param[in] func\n Reference to function to be called\n\n @param[in] buffer\n String representing a map to be deserialized into arguments of the function\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @param[in] resolve_callback\n Pointer to function that will be executed when task completion\n @param[in] void *\n Value representing the result of the future resolution\n @param[in] void *\n A reference to @data that will be used as a closure for the chain\n @return\n Value containing the result of the operation,\n it will be wrapped into a future later on to be returned by the function\n\n @param[in] reject_callback\n Pointer to function that will be executed when task error (signature is identical as resolve_callback)\n\n @param[in] data\n Pointer to a context that will act as a closure for the chain\n\n @return\n Pointer to value containing the result of the call returned by @resolve_callback or @reject_callback wrapped in a future"] + pub fn metacallfms_await( + func: *mut ::std::os::raw::c_void, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + resolve_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + reject_callback: ::std::option::Option< + unsafe extern "C" fn( + arg1: *mut ::std::os::raw::c_void, + arg2: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >, + data: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get the class by @name\n\n @param[in] name\n Name of the class\n\n @return\n Class reference, null if the class does not exist"] + pub fn metacall_class(name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a class method anonymously by value array @args (this procedure assumes there's no overloaded methods and does type conversion on values)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallv_class( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a class method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallt_class( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ret: metacall_value_id, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Create a new object instance from @cls by value array @args\n\n @param[in] cls\n Pointer to the class\n\n @param[in] name\n Name of the new object\n\n @param[in] args\n Array of pointers constructor parameters\n\n @param[in] size\n Number of elements of constructor parameters\n\n @return\n Pointer to the new object value instance"] + pub fn metacall_class_new( + cls: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get an attribute from @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the class attribute value or NULL if an error occurred"] + pub fn metacall_class_static_get( + cls: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Set an attribute to @cls by @key name\n\n @param[in] cls\n Pointer to the class\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] + pub fn metacall_class_static_set( + cls: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Call an object method anonymously by value array @args\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallv_object( + obj: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Call a object method anonymously by value array @args and return value type @ret (helps to resolve overloading methods)\n\n @param[in] obj\n Pointer to the object\n\n @param[in] name\n Name of the method\n\n @param[in] ret\n Type of the return value of the method\n\n @param[in] args\n Array of pointers to data\n\n @param[in] size\n Number of elements of args array\n\n @return\n Pointer to value containing the result of the call"] + pub fn metacallt_object( + obj: *mut ::std::os::raw::c_void, + name: *const ::std::os::raw::c_char, + ret: metacall_value_id, + args: *mut *mut ::std::os::raw::c_void, + size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get an attribute from @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to get\n\n @return\n Pointer to the object attribute value or NULL if an error occurred"] + pub fn metacall_object_get( + obj: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Set an attribute to @obj by @key name\n\n @param[in] obj\n Pointer to the object\n\n @param[in] key\n Name of the attribute to set\n\n @param[in] value\n Value to set\n\n @return\n Non-zero integer if an error ocurred"] + pub fn metacall_object_set( + obj: *mut ::std::os::raw::c_void, + key: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the value contained by throwable object @th\n\n @param[in] th\n Pointer to the throwable object\n\n @return\n Pointer to the value inside of the throwable or NULL in case of error"] + pub fn metacall_throwable_value(th: *mut ::std::os::raw::c_void) + -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Provide information about all loaded objects\n\n @param[out] size\n Size in bytes of return buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n String containing introspection information"] + pub fn metacall_inspect( + size: *mut usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Provide information about all loaded objects as a value\n\n @return\n Value containing introspection information"] + pub fn metacall_inspect_value() -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Convert the value @v to serialized string\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] v\n Reference to the value\n\n @param[out] size\n Size of new allocated string\n\n @param[in] allocator\n Pointer to allocator will allocate the string\n\n @return\n New allocated string containing stringified value"] + pub fn metacall_serialize( + name: *const ::std::os::raw::c_char, + v: *mut ::std::os::raw::c_void, + size: *mut usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Convert the string @buffer to value\n\n @param[in] name\n Name of the serial to be used\n\n @param[in] buffer\n String to be deserialized\n\n @param[in] size\n Size of string @buffer\n\n @param[in] allocator\n Pointer to allocator will allocate the value\n\n @return\n New allocated value representing the string (must be freed)"] + pub fn metacall_deserialize( + name: *const ::std::os::raw::c_char, + buffer: *const ::std::os::raw::c_char, + size: usize, + allocator: *mut ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Clear handle from memory and unload related resources\n\n @param[in] handle\n Reference to the handle to be unloaded\n\n @return\n Zero if success, different from zero otherwise"] + pub fn metacall_clear(handle: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + #[doc = " @brief\n Get the plugin extension handle to be used for loading plugins\n\n @return\n Pointer to the extension handle, or null if it failed to load"] + pub fn metacall_plugin_extension() -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get the handle containing all the functionality of the plugins from core\n\n @return\n Pointer to the core plugin handle, or null if it failed to load"] + pub fn metacall_plugin_core() -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + #[doc = " @brief\n Get the plugin extension path to be used for accessing the plugins folder\n\n @return\n String containing the core plugin path, or null if it failed to load the plugin extension"] + pub fn metacall_plugin_path() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Destroy MetaCall library"] + pub fn metacall_destroy(); +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version struct\n\n @return\n Static struct containing unpacked version"] + pub fn metacall_version() -> *const metacall_version_type; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is @major,\n I is @minor and P is @patch\n\n @param[in] major\n Unsigned integer representing major version\n\n @param[in] minor\n Unsigned integer representing minor version\n\n @param[in] patch\n Unsigned integer representing patch version\n\n @return\n Hexadecimal integer containing packed version"] + pub fn metacall_version_hex_make( + major: ::std::os::raw::c_uint, + minor: ::std::os::raw::c_uint, + patch: ::std::os::raw::c_uint, + ) -> u32; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version hexadecimal value\n with format 0xMMIIPPPP where M is major,\n I is minor and P is patch\n\n @return\n Hexadecimal integer containing packed version"] + pub fn metacall_version_hex() -> u32; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version string\n\n @return\n Static string containing module version"] + pub fn metacall_version_str() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version revision string\n\n @return\n Static string containing module version revision"] + pub fn metacall_version_revision() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module version name\n\n @return\n Static string containing module version name"] + pub fn metacall_version_name() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + #[doc = " @brief\n Provide the module information\n\n @return\n Static string containing module information"] + pub fn metacall_print_info() -> *const ::std::os::raw::c_char; +} From 8dd3f55cc6209831e933c85615f30fb9d392f878 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 9 Sep 2025 21:55:09 +0200 Subject: [PATCH 091/109] Improved rs port. --- source/ports/rs_port/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 98e2596bf..30c840a64 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -173,7 +173,7 @@ fn find_metacall_library() -> Result<LibraryPath, Box<dyn std::error::Error>> { .into()) } -fn define_library_search_path(env_var: &str, separator: &str, path: &PathBuf) -> String { +fn define_library_search_path(env_var: &str, separator: &str, path: &Path) -> String { // Get the current value of the env var, if any let existing = env::var(env_var).unwrap_or_default(); let path_str: String = String::from(path.to_str().unwrap()); From 9070d7fc4d5de02202d29384728dfe97f747cc19 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 9 Sep 2025 22:32:14 +0200 Subject: [PATCH 092/109] Exposed the rs port find method for metacall library. --- source/ports/rs_port/Cargo.toml | 5 +- source/ports/rs_port/README.md | 18 ++ source/ports/rs_port/build.rs | 255 +--------------------------- source/ports/rs_port/sys/Cargo.toml | 7 + source/ports/rs_port/sys/src/lib.rs | 255 ++++++++++++++++++++++++++++ source/ports/rs_port/upload.sh | 2 + 6 files changed, 288 insertions(+), 254 deletions(-) create mode 100644 source/ports/rs_port/sys/Cargo.toml create mode 100644 source/ports/rs_port/sys/src/lib.rs diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index c0ce796a1..781bafb19 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" name = "metacall" readme = "README.md" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" -version = "0.5.0" +version = "0.5.1" [lib] crate-type = ["lib"] @@ -18,3 +18,6 @@ path = "src/lib.rs" [dependencies] metacall-inline = { path = "./inline", version = "0.2.0" } + +[build-dependencies] +metacall-sys = { path = "./sys", version = "0.1.0" } diff --git a/source/ports/rs_port/README.md b/source/ports/rs_port/README.md index 8b9a5531c..a29580a55 100644 --- a/source/ports/rs_port/README.md +++ b/source/ports/rs_port/README.md @@ -15,6 +15,24 @@ MetaCall is a C plugin based library. This crate wraps the C library into Rust, curl -sL https://raw.githubusercontent.com/metacall/install/master/install.sh | sh ``` +# Linking + +If your project uses MetaCall in a folder that is not in the system path, we encourage to use `metacall-sys` crate as a `build-dependecy`. By this way you will be able to locate and link MetaCall directly in your build system. For example: + +`Cargo.toml`: +```toml +[build-dependencies] +metacall-sys = { path = "./sys", version = "0.1.0" } +``` + +`build.rs`: +```rust +fn main() { + // Find MetaCall library + metacall_sys::build(); +} +``` + # Example `sum.ts` diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 30c840a64..efb09e8f6 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -1,255 +1,4 @@ -use std::{ - env, fs, - path::{Path, PathBuf}, - vec, -}; - -// Search for MetaCall libraries in platform-specific locations -// Handle custom installation paths via environment variables -// Find configuration files recursively -// Provide helpful error messages when things aren't found - -/// Represents the install paths for a platform -struct InstallPath { - paths: Vec<PathBuf>, - names: Vec<&'static str>, -} - -/// Represents the match of a library when it's found -struct LibraryPath { - path: PathBuf, - library: String, -} - -/// Find files recursively in a directory matching a pattern -fn find_files_recursively<P: AsRef<Path>>( - root_dir: P, - filename: &str, - max_depth: Option<usize>, -) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> { - let mut matches = Vec::new(); - let mut stack = vec![(root_dir.as_ref().to_path_buf(), 0)]; - - while let Some((current_dir, depth)) = stack.pop() { - if let Some(max) = max_depth { - if depth > max { - continue; - } - } - - if let Ok(entries) = fs::read_dir(¤t_dir) { - for entry in entries.flatten() { - let path = entry.path(); - - if path.is_file() { - // Simple filename comparison instead of regex - if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { - if file_name == filename { - matches.push(path); - } - } - } else if path.is_dir() { - stack.push((path, depth + 1)); - } - } - } - } - - Ok(matches) -} - -fn platform_install_paths() -> Result<InstallPath, Box<dyn std::error::Error>> { - if cfg!(target_os = "windows") { - // Defaults to path: C:\Users\Default\AppData\Local - let local_app_data = env::var("LOCALAPPDATA") - .unwrap_or_else(|_| String::from("C:\\Users\\Default\\AppData\\Local")); - - Ok(InstallPath { - paths: vec![PathBuf::from(local_app_data) - .join("MetaCall") - .join("metacall")], - names: vec!["metacall.lib"], - }) - } else if cfg!(target_os = "macos") { - Ok(InstallPath { - paths: vec![ - PathBuf::from("/opt/homebrew/lib/"), - PathBuf::from("/usr/local/lib/"), - ], - names: vec!["libmetacall.dylib"], - }) - } else if cfg!(target_os = "linux") { - Ok(InstallPath { - paths: vec![PathBuf::from("/usr/local/lib/"), PathBuf::from("/gnu/lib/")], - names: vec!["libmetacall.so"], - }) - } else { - Err(format!("Platform {} not supported", env::consts::OS).into()) - } -} - -/// Get search paths, checking for custom installation path first -fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { - // First, check if user specified a custom path - if let Ok(custom_path) = env::var("METACALL_INSTALL_PATH") { - // For custom paths, we need to search for any metacall library variant - return Ok(InstallPath { - paths: vec![PathBuf::from(custom_path)], - names: vec![ - "libmetacall.so", - "libmetacalld.so", - "libmetacall.dylib", - "libmetacalld.dylib", - "metacall.lib", - "metacalld.lib", - ], - }); - } - - // Fall back to platform-specific paths - platform_install_paths() -} - -/// Get the parent path and library name -fn get_parent_and_library(path: &Path) -> Option<(PathBuf, String)> { - let parent = path.parent()?.to_path_buf(); - - // Get the file stem (filename without extension) - let stem = path.file_stem()?.to_str()?; - - // Remove "lib" prefix if present - let cleaned_stem = stem.strip_prefix("lib").unwrap_or(stem).to_string(); - - Some((parent, cleaned_stem)) -} - -/// Find the MetaCall library -/// This orchestrates the search process -fn find_metacall_library() -> Result<LibraryPath, Box<dyn std::error::Error>> { - let search_config = get_search_config()?; - - // Search in each configured path - for search_path in &search_config.paths { - for name in &search_config.names { - // Search with no limit in depth - match find_files_recursively(search_path, name, None) { - Ok(files) if !files.is_empty() => { - let found_lib = fs::canonicalize(&files[0])?; - - match get_parent_and_library(&found_lib) { - Some((parent, name)) => { - return Ok(LibraryPath { - path: parent, - library: name, - }) - } - None => continue, - }; - } - Ok(_) => { - // No files found in this path, continue searching - continue; - } - Err(e) => { - eprintln!("Error searching in {}: {}", search_path.display(), e); - continue; - } - } - } - } - - // If we get here, library wasn't found - let search_paths: Vec<String> = search_config - .paths - .iter() - .map(|p| p.display().to_string()) - .collect(); - - Err(format!( - "MetaCall library not found. Searched in: {}. \ - If you have it installed elsewhere, set METACALL_INSTALL_PATH environment variable.", - search_paths.join(", ") - ) - .into()) -} - -fn define_library_search_path(env_var: &str, separator: &str, path: &Path) -> String { - // Get the current value of the env var, if any - let existing = env::var(env_var).unwrap_or_default(); - let path_str: String = String::from(path.to_str().unwrap()); - - // Append to it - let combined = if existing.is_empty() { - path_str - } else { - format!("{}{}{}", existing, separator, path_str) - }; - - format!("{}={}", env_var, combined) -} - fn main() { - // When running tests from CMake - if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") { - // Link search path to build folder - println!("cargo:rustc-link-search=native={val}"); - - // Link against correct version of metacall - match env::var("CMAKE_BUILD_TYPE") { - Ok(val) => { - if val == "Debug" { - // Try to link the debug version when running tests - println!("cargo:rustc-link-lib=dylib=metacalld"); - } else { - println!("cargo:rustc-link-lib=dylib=metacall"); - } - } - Err(_) => { - println!("cargo:rustc-link-lib=dylib=metacall"); - } - } - } else { - // When building from Cargo, try to find MetaCall - match find_metacall_library() { - Ok(lib_path) => { - // Define linker flags - println!("cargo:rustc-link-search=native={}", lib_path.path.display()); - println!("cargo:rustc-link-lib=dylib={}", lib_path.library); - - // Set the runtime environment variable for finding the library during tests - #[cfg(target_os = "linux")] - const ENV_VAR: &str = "LD_LIBRARY_PATH"; - - #[cfg(target_os = "macos")] - const ENV_VAR: &str = "DYLD_LIBRARY_PATH"; - - #[cfg(target_os = "windows")] - const ENV_VAR: &str = "PATH"; - - #[cfg(target_os = "aix")] - const ENV_VAR: &str = "LIBPATH"; - - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "aix"))] - const SEPARATOR: &str = ":"; - - #[cfg(target_os = "windows")] - const SEPARATOR: &str = ";"; - - println!( - "cargo:rustc-env={}", - define_library_search_path(ENV_VAR, SEPARATOR, &lib_path.path) - ); - } - Err(e) => { - // Print the error - eprintln!( - "Failed to find MetaCall library with: {e} \ - Still trying to link in case the library is in system paths" - ); - - // Still try to link in case the library is in system paths - println!("cargo:rustc-link-lib=dylib=metacall") - } - } - } + // Find MetaCall library + metacall_sys::build(); } diff --git a/source/ports/rs_port/sys/Cargo.toml b/source/ports/rs_port/sys/Cargo.toml new file mode 100644 index 000000000..4e4b15ffa --- /dev/null +++ b/source/ports/rs_port/sys/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "metacall-sys" +version = "0.1.0" +repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" +edition = "2021" +license = "Apache-2.0" +description = "Crate for finding metacall library in the system." diff --git a/source/ports/rs_port/sys/src/lib.rs b/source/ports/rs_port/sys/src/lib.rs new file mode 100644 index 000000000..02814c532 --- /dev/null +++ b/source/ports/rs_port/sys/src/lib.rs @@ -0,0 +1,255 @@ +use std::{ + env, fs, + path::{Path, PathBuf}, + vec, +}; + +// Search for MetaCall libraries in platform-specific locations +// Handle custom installation paths via environment variables +// Find configuration files recursively +// Provide helpful error messages when things aren't found + +/// Represents the install paths for a platform +struct InstallPath { + paths: Vec<PathBuf>, + names: Vec<&'static str>, +} + +/// Represents the match of a library when it's found +struct LibraryPath { + path: PathBuf, + library: String, +} + +/// Find files recursively in a directory matching a pattern +fn find_files_recursively<P: AsRef<Path>>( + root_dir: P, + filename: &str, + max_depth: Option<usize>, +) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> { + let mut matches = Vec::new(); + let mut stack = vec![(root_dir.as_ref().to_path_buf(), 0)]; + + while let Some((current_dir, depth)) = stack.pop() { + if let Some(max) = max_depth { + if depth > max { + continue; + } + } + + if let Ok(entries) = fs::read_dir(¤t_dir) { + for entry in entries.flatten() { + let path = entry.path(); + + if path.is_file() { + // Simple filename comparison instead of regex + if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) { + if file_name == filename { + matches.push(path); + } + } + } else if path.is_dir() { + stack.push((path, depth + 1)); + } + } + } + } + + Ok(matches) +} + +fn platform_install_paths() -> Result<InstallPath, Box<dyn std::error::Error>> { + if cfg!(target_os = "windows") { + // Defaults to path: C:\Users\Default\AppData\Local + let local_app_data = env::var("LOCALAPPDATA") + .unwrap_or_else(|_| String::from("C:\\Users\\Default\\AppData\\Local")); + + Ok(InstallPath { + paths: vec![PathBuf::from(local_app_data) + .join("MetaCall") + .join("metacall")], + names: vec!["metacall.lib"], + }) + } else if cfg!(target_os = "macos") { + Ok(InstallPath { + paths: vec![ + PathBuf::from("/opt/homebrew/lib/"), + PathBuf::from("/usr/local/lib/"), + ], + names: vec!["libmetacall.dylib"], + }) + } else if cfg!(target_os = "linux") { + Ok(InstallPath { + paths: vec![PathBuf::from("/usr/local/lib/"), PathBuf::from("/gnu/lib/")], + names: vec!["libmetacall.so"], + }) + } else { + Err(format!("Platform {} not supported", env::consts::OS).into()) + } +} + +/// Get search paths, checking for custom installation path first +fn get_search_config() -> Result<InstallPath, Box<dyn std::error::Error>> { + // First, check if user specified a custom path + if let Ok(custom_path) = env::var("METACALL_INSTALL_PATH") { + // For custom paths, we need to search for any metacall library variant + return Ok(InstallPath { + paths: vec![PathBuf::from(custom_path)], + names: vec![ + "libmetacall.so", + "libmetacalld.so", + "libmetacall.dylib", + "libmetacalld.dylib", + "metacall.lib", + "metacalld.lib", + ], + }); + } + + // Fall back to platform-specific paths + platform_install_paths() +} + +/// Get the parent path and library name +fn get_parent_and_library(path: &Path) -> Option<(PathBuf, String)> { + let parent = path.parent()?.to_path_buf(); + + // Get the file stem (filename without extension) + let stem = path.file_stem()?.to_str()?; + + // Remove "lib" prefix if present + let cleaned_stem = stem.strip_prefix("lib").unwrap_or(stem).to_string(); + + Some((parent, cleaned_stem)) +} + +/// Find the MetaCall library +/// This orchestrates the search process +fn find_metacall_library() -> Result<LibraryPath, Box<dyn std::error::Error>> { + let search_config = get_search_config()?; + + // Search in each configured path + for search_path in &search_config.paths { + for name in &search_config.names { + // Search with no limit in depth + match find_files_recursively(search_path, name, None) { + Ok(files) if !files.is_empty() => { + let found_lib = fs::canonicalize(&files[0])?; + + match get_parent_and_library(&found_lib) { + Some((parent, name)) => { + return Ok(LibraryPath { + path: parent, + library: name, + }) + } + None => continue, + }; + } + Ok(_) => { + // No files found in this path, continue searching + continue; + } + Err(e) => { + eprintln!("Error searching in {}: {}", search_path.display(), e); + continue; + } + } + } + } + + // If we get here, library wasn't found + let search_paths: Vec<String> = search_config + .paths + .iter() + .map(|p| p.display().to_string()) + .collect(); + + Err(format!( + "MetaCall library not found. Searched in: {}. \ + If you have it installed elsewhere, set METACALL_INSTALL_PATH environment variable.", + search_paths.join(", ") + ) + .into()) +} + +fn define_library_search_path(env_var: &str, separator: &str, path: &Path) -> String { + // Get the current value of the env var, if any + let existing = env::var(env_var).unwrap_or_default(); + let path_str: String = String::from(path.to_str().unwrap()); + + // Append to it + let combined = if existing.is_empty() { + path_str + } else { + format!("{}{}{}", existing, separator, path_str) + }; + + format!("{}={}", env_var, combined) +} + +pub fn build() { + // When running tests from CMake + if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") { + // Link search path to build folder + println!("cargo:rustc-link-search=native={val}"); + + // Link against correct version of metacall + match env::var("CMAKE_BUILD_TYPE") { + Ok(val) => { + if val == "Debug" { + // Try to link the debug version when running tests + println!("cargo:rustc-link-lib=dylib=metacalld"); + } else { + println!("cargo:rustc-link-lib=dylib=metacall"); + } + } + Err(_) => { + println!("cargo:rustc-link-lib=dylib=metacall"); + } + } + } else { + // When building from Cargo, try to find MetaCall + match find_metacall_library() { + Ok(lib_path) => { + // Define linker flags + println!("cargo:rustc-link-search=native={}", lib_path.path.display()); + println!("cargo:rustc-link-lib=dylib={}", lib_path.library); + + // Set the runtime environment variable for finding the library during tests + #[cfg(target_os = "linux")] + const ENV_VAR: &str = "LD_LIBRARY_PATH"; + + #[cfg(target_os = "macos")] + const ENV_VAR: &str = "DYLD_LIBRARY_PATH"; + + #[cfg(target_os = "windows")] + const ENV_VAR: &str = "PATH"; + + #[cfg(target_os = "aix")] + const ENV_VAR: &str = "LIBPATH"; + + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "aix"))] + const SEPARATOR: &str = ":"; + + #[cfg(target_os = "windows")] + const SEPARATOR: &str = ";"; + + println!( + "cargo:rustc-env={}", + define_library_search_path(ENV_VAR, SEPARATOR, &lib_path.path) + ); + } + Err(e) => { + // Print the error + eprintln!( + "Failed to find MetaCall library with: {e} \ + Still trying to link in case the library is in system paths" + ); + + // Still try to link in case the library is in system paths + println!("cargo:rustc-link-lib=dylib=metacall") + } + } + } +} diff --git a/source/ports/rs_port/upload.sh b/source/ports/rs_port/upload.sh index c85fac147..4156acb04 100644 --- a/source/ports/rs_port/upload.sh +++ b/source/ports/rs_port/upload.sh @@ -31,6 +31,8 @@ function publish() { } # Publish +cd sys +publish metacall-sys cd inline publish metacall-inline cd .. From 51884008ff573bfab69e5f2601e4dc105f0cfcda Mon Sep 17 00:00:00 2001 From: Fahd Ashour <fahd.fady212@gmail.com> Date: Tue, 16 Sep 2025 22:03:54 +0300 Subject: [PATCH 093/109] edit rs port readme and providing relatable links (#575) * edit rs port readme and providing relatable links * Update README.md --------- Co-authored-by: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> --- source/ports/rs_port/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ports/rs_port/README.md b/source/ports/rs_port/README.md index a29580a55..d8cc3e256 100644 --- a/source/ports/rs_port/README.md +++ b/source/ports/rs_port/README.md @@ -17,12 +17,12 @@ curl -sL https://raw.githubusercontent.com/metacall/install/master/install.sh | # Linking -If your project uses MetaCall in a folder that is not in the system path, we encourage to use `metacall-sys` crate as a `build-dependecy`. By this way you will be able to locate and link MetaCall directly in your build system. For example: +If your project uses MetaCall in a folder that is not in the system path, we encourage to use [`metacall-sys`](https://crates.io/crates/metacall-sys) crate as a [`build-dependecy`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#build-dependencies). By this way you will be able to locate and link MetaCall directly in your build system. For example: `Cargo.toml`: ```toml [build-dependencies] -metacall-sys = { path = "./sys", version = "0.1.0" } +metacall-sys = "0.1.1" ``` `build.rs`: From 37fe7cfa563b343a2524582f4bf98e775c5f63db Mon Sep 17 00:00:00 2001 From: Fahd Ashour <fahd.fady212@gmail.com> Date: Tue, 16 Sep 2025 22:17:20 +0300 Subject: [PATCH 094/109] rust metacall-sys crate: enhance searching with RPATH handling for C Libs discovery across platforms (binary) and improve metacall-sys cargo (#576) * feat(rs metacall-sys): enhance searching with RPATH handling for library discovery across platforms (binary) * Update Cargo.toml * Update Cargo.toml * Update lib.rs --------- Co-authored-by: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com> --- source/ports/rs_port/sys/Cargo.toml | 12 +++++++-- source/ports/rs_port/sys/src/lib.rs | 42 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/source/ports/rs_port/sys/Cargo.toml b/source/ports/rs_port/sys/Cargo.toml index 4e4b15ffa..99378eac4 100644 --- a/source/ports/rs_port/sys/Cargo.toml +++ b/source/ports/rs_port/sys/Cargo.toml @@ -1,7 +1,15 @@ [package] name = "metacall-sys" -version = "0.1.0" -repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" +version = "0.1.1" +repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port/sys" +keywords = ["ffi", "bindings", "metacall"] edition = "2021" license = "Apache-2.0" description = "Crate for finding metacall library in the system." + +[lib] +crate-type = ["lib"] +doctest = false +edition = "2021" +name = "metacall_sys" +path = "src/lib.rs" diff --git a/source/ports/rs_port/sys/src/lib.rs b/source/ports/rs_port/sys/src/lib.rs index 02814c532..f33176aaf 100644 --- a/source/ports/rs_port/sys/src/lib.rs +++ b/source/ports/rs_port/sys/src/lib.rs @@ -188,6 +188,45 @@ fn define_library_search_path(env_var: &str, separator: &str, path: &Path) -> St format!("{}={}", env_var, combined) } +/// Set RPATH for runtime library discovery +/// This binaries work outside cargo +fn set_rpath(lib_path: &Path) { + let path_str = lib_path.to_str().unwrap(); + + #[cfg(target_os = "linux")] + { + // On Linux, use RPATH with $ORIGIN for relocatable binaries + println!("cargo:rustc-link-arg=-Wl,-rpath,{}", path_str); + // Also set a backup rpath relative to the executable location + println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN"); + println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../lib"); + } + + #[cfg(target_os = "macos")] + { + // On macOS, use @rpath and @loader_path + println!("cargo:rustc-link-arg=-Wl,-rpath,{}", path_str); + // Also set loader-relative paths for relocatable binaries + println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path"); + println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path/../lib"); + } + + #[cfg(target_os = "aix")] + { + // Add default system library paths to avoid breaking standard lookup + println!("cargo:rustc-link-arg=-Wl,-blibpath:{}:/usr/lib:/lib", path_str); + } + + #[cfg(target_os = "windows")] + { + // Windows doesn't use RPATH, but we can inform the user + println!( + "cargo:warning=On Windows, make sure {} is in your PATH or next to your executable", + path_str + ); + } +} + pub fn build() { // When running tests from CMake if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") { @@ -216,6 +255,9 @@ pub fn build() { println!("cargo:rustc-link-search=native={}", lib_path.path.display()); println!("cargo:rustc-link-lib=dylib={}", lib_path.library); + // Set RPATH so the binary can find libraries at runtime + set_rpath(&lib_path.path); + // Set the runtime environment variable for finding the library during tests #[cfg(target_os = "linux")] const ENV_VAR: &str = "LD_LIBRARY_PATH"; From b50d11ca47001d738cd5587d7d9551d6ed779d61 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 16 Sep 2025 21:43:41 +0200 Subject: [PATCH 095/109] Trying windows rust test again. --- .github/workflows/release-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 528eda6b7..ff564a74e 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] # TODO: , windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: Check out the repo uses: actions/checkout@v4 From b77ae9488e498f4749bf3c5cf00cdc05c7dc4cc7 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 16 Sep 2025 21:45:37 +0200 Subject: [PATCH 096/109] Improve rust ci. --- .github/workflows/release-rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index ff564a74e..fcfd917dc 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -6,6 +6,7 @@ on: push: branches: [ master, develop ] paths: + - '.github/workflows/release-rust.yml' - 'source/ports/rs_port/**' concurrency: From 3f1c5d05962ab93bd29edf3a01c3ae979e050915 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 16 Sep 2025 21:59:15 +0200 Subject: [PATCH 097/109] Remove windows. --- .github/workflows/release-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index fcfd917dc..9ef5e2ec1 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-latest] # TODO: , windows-latest] steps: - name: Check out the repo uses: actions/checkout@v4 From 4d095b291b9caa5d7000acb29854f313ceb918c8 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 17 Sep 2025 21:36:24 +0200 Subject: [PATCH 098/109] Corrected versions of rs_port. --- source/ports/rs_port/Cargo.toml | 4 ++-- source/ports/rs_port/README.md | 2 +- source/ports/rs_port/sys/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index 781bafb19..c0e51713a 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" name = "metacall" readme = "README.md" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port" -version = "0.5.1" +version = "0.5.2" [lib] crate-type = ["lib"] @@ -20,4 +20,4 @@ path = "src/lib.rs" metacall-inline = { path = "./inline", version = "0.2.0" } [build-dependencies] -metacall-sys = { path = "./sys", version = "0.1.0" } +metacall-sys = { path = "./sys", version = "0.1.2" } diff --git a/source/ports/rs_port/README.md b/source/ports/rs_port/README.md index d8cc3e256..53edd0936 100644 --- a/source/ports/rs_port/README.md +++ b/source/ports/rs_port/README.md @@ -22,7 +22,7 @@ If your project uses MetaCall in a folder that is not in the system path, we enc `Cargo.toml`: ```toml [build-dependencies] -metacall-sys = "0.1.1" +metacall-sys = "0.1.2" ``` `build.rs`: diff --git a/source/ports/rs_port/sys/Cargo.toml b/source/ports/rs_port/sys/Cargo.toml index 99378eac4..398dcaf52 100644 --- a/source/ports/rs_port/sys/Cargo.toml +++ b/source/ports/rs_port/sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "metacall-sys" -version = "0.1.1" +version = "0.1.2" repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port/sys" keywords = ["ffi", "bindings", "metacall"] edition = "2021" From c769cc88f24fd10b56ef5dd64b020a8e0c487a32 Mon Sep 17 00:00:00 2001 From: Thomas <thomas.gummerson@piql.com> Date: Thu, 18 Sep 2025 20:15:11 +0200 Subject: [PATCH 099/109] Replace relevant EXPECT_EQ / ASSERT_EQ with EXPECT_STREQ / ASSERT_STREQ (#579) --- .../tests/adt_trie_test/source/adt_trie_test.cpp | 4 ++-- source/tests/detour_test/source/detour_test.cpp | 2 +- .../tests/dynlink_test/source/dynlink_test.cpp | 6 +++--- .../environment_test/source/environment_test.cpp | 12 ++++++------ source/tests/log_test/source/log_test.cpp | 2 +- .../metacall_configuration_exec_path_test.cpp | 2 +- ...all_configuration_exec_relative_path_test.cpp | 2 +- .../metacall_cs_test/source/metacall_cs_test.cpp | 2 +- .../source/metacall_distributable_test.cpp | 10 +++++----- .../source/metacall_ducktype_test.cpp | 8 ++++---- .../source/metacall_function_test.cpp | 2 +- .../source/metacall_handle_get_test.cpp | 4 ++-- .../source/metacall_java_test.cpp | 4 ++-- .../source/metacall_load_configuration_test.cpp | 6 +++--- .../source/metacall_map_await_test.cpp | 2 +- .../source/metacall_map_test.cpp | 2 +- .../source/metacall_node_exception_test.cpp | 4 ++-- .../source/metacall_node_extension_test.cpp | 2 +- .../source/metacall_node_port_test.cpp | 2 +- .../source/metacall_python_dict_test.cpp | 6 +++--- .../source/metacall_python_exception_test.cpp | 8 ++++---- .../source/metacall_python_loader_port_test.cpp | 4 ++-- .../source/metacall_python_open_test.cpp | 4 ++-- .../source/metacall_python_port_test.cpp | 2 +- .../source/metacall_return_monad_test.cpp | 2 +- .../metacall_ruby_parser_integration_test.cpp | 2 +- .../metacall_rust_load_from_package_dep_test.cpp | 2 +- .../metacall_rust_load_from_package_test.cpp | 2 +- .../source/metacall_rust_test.cpp | 4 ++-- .../tests/metacall_test/source/metacall_test.cpp | 12 ++++++------ .../metacall_test/source/metacall_test_split.cpp | 10 +++++----- .../source/metacall_typescript_tsx_test.cpp | 2 +- .../source/metacall_version_test.cpp | 2 +- .../source/reflect_object_class_test.cpp | 4 ++-- source/tests/serial_test/source/serial_test.cpp | 16 ++++++++-------- 35 files changed, 80 insertions(+), 80 deletions(-) diff --git a/source/tests/adt_trie_test/source/adt_trie_test.cpp b/source/tests/adt_trie_test/source/adt_trie_test.cpp index cb1edbf28..1d9541dc0 100644 --- a/source/tests/adt_trie_test/source/adt_trie_test.cpp +++ b/source/tests/adt_trie_test/source/adt_trie_test.cpp @@ -123,7 +123,7 @@ TEST_F(adt_trie_test, DefaultConstructor) log_write("metacall", LOG_LEVEL_DEBUG, "%" PRIuS " -> %s", iterator, value_str); - EXPECT_EQ((int)0, (int)strcmp(values_str[keys_size - iterator - 1], value_str)); + EXPECT_STREQ(values_str[keys_size - iterator - 1], value_str); vector_pop_back(keys_copy); } @@ -144,7 +144,7 @@ TEST_F(adt_trie_test, DefaultConstructor) log_write("metacall", LOG_LEVEL_DEBUG, "%s/", key_str); - EXPECT_EQ((int)0, (int)strcmp(keys_str[iterator], key_str)); + EXPECT_STREQ(keys_str[iterator], key_str); } vector_pop_back(keys); diff --git a/source/tests/detour_test/source/detour_test.cpp b/source/tests/detour_test/source/detour_test.cpp index 15b56ec58..4882867e8 100644 --- a/source/tests/detour_test/source/detour_test.cpp +++ b/source/tests/detour_test/source/detour_test.cpp @@ -111,7 +111,7 @@ TEST_F(detour_test, DefaultConstructor) ASSERT_NE((detour)NULL, (detour)d); - EXPECT_EQ((int)0, (int)strcmp(name, detour_name(d))); + EXPECT_STREQ(name, detour_name(d)); /* Load detour of detour library */ handle = detour_load_file(d, NULL); diff --git a/source/tests/dynlink_test/source/dynlink_test.cpp b/source/tests/dynlink_test/source/dynlink_test.cpp index 8bebf4526..0119510ca 100644 --- a/source/tests/dynlink_test/source/dynlink_test.cpp +++ b/source/tests/dynlink_test/source/dynlink_test.cpp @@ -101,7 +101,7 @@ TEST_F(dynlink_test, DefaultConstructor) log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object file: %s", dynlink_get_path(handle)); - EXPECT_EQ((int)0, (int)strcmp(library_name, dynlink_get_name(handle))); + EXPECT_STREQ(library_name, dynlink_get_name(handle)); if (handle != NULL) { @@ -146,8 +146,8 @@ TEST_F(dynlink_test, DefaultConstructor) log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object file name: %s", dynlink_get_path(handle)); log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object file: %s", dynlink_get_name(handle)); - EXPECT_EQ((int)0, (int)strcmp(absolute_path, dynlink_get_path(handle))); - EXPECT_EQ((int)0, (int)strcmp(library_name, dynlink_get_name(handle))); + EXPECT_STREQ(absolute_path, dynlink_get_path(handle)); + EXPECT_STREQ(library_name, dynlink_get_name(handle)); if (handle != NULL) { diff --git a/source/tests/environment_test/source/environment_test.cpp b/source/tests/environment_test/source/environment_test.cpp index dee634141..576dfb28a 100644 --- a/source/tests/environment_test/source/environment_test.cpp +++ b/source/tests/environment_test/source/environment_test.cpp @@ -39,7 +39,7 @@ TEST_F(environment_test, variable_text) ASSERT_NE((const char *)NULL, (const char *)variable_text); - EXPECT_EQ((int)0, (int)strcmp(variable_text, "abcd")); + EXPECT_STREQ(variable_text, "abcd"); environment_variable_destroy(variable_text); } @@ -52,7 +52,7 @@ TEST_F(environment_test, variable_text_default) ASSERT_NE((const char *)NULL, (const char *)variable_text); - EXPECT_EQ((int)0, (int)strcmp(variable_text, "default")); + EXPECT_STREQ(variable_text, "default"); environment_variable_destroy(variable_text); } @@ -63,7 +63,7 @@ TEST_F(environment_test, variable_static) const char *variable_text_static = environment_variable_get(variable_text_name, "default"); - EXPECT_EQ((int)0, (int)strcmp(variable_text_static, "abcd")); + EXPECT_STREQ(variable_text_static, "abcd"); } TEST_F(environment_test, variable_path) @@ -74,7 +74,7 @@ TEST_F(environment_test, variable_path) ASSERT_NE((const char *)NULL, (const char *)variable_path); - EXPECT_EQ((int)0, (int)strcmp(variable_path, "abcd" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR)); + EXPECT_STREQ(variable_path, "abcd" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); environment_variable_path_destroy(variable_path); } @@ -87,7 +87,7 @@ TEST_F(environment_test, variable_path_default) ASSERT_NE((const char *)NULL, (const char *)variable_path); - EXPECT_EQ((int)0, (int)strcmp(variable_path, "default_path" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR)); + EXPECT_STREQ(variable_path, "default_path" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); environment_variable_path_destroy(variable_path); } @@ -100,7 +100,7 @@ TEST_F(environment_test, variable_path_sanitized) ASSERT_NE((const char *)NULL, (const char *)variable_path); - EXPECT_EQ((int)0, (int)strcmp(variable_path, "abcd" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR)); + EXPECT_STREQ(variable_path, "abcd" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); environment_variable_path_destroy(variable_path); } diff --git a/source/tests/log_test/source/log_test.cpp b/source/tests/log_test/source/log_test.cpp index 2a1505e71..3e1121bc7 100644 --- a/source/tests/log_test/source/log_test.cpp +++ b/source/tests/log_test/source/log_test.cpp @@ -85,7 +85,7 @@ TEST_F(log_test, DefaultConstructor) unsigned int value = *((unsigned int *)value_ptr); - EXPECT_EQ((int)0, (int)strcmp(log_name_list[value].name, key)); + EXPECT_STREQ(log_name_list[value].name, key); } EXPECT_EQ((int)log_map_destroy(map), (int)0); diff --git a/source/tests/metacall_configuration_exec_path_test/source/metacall_configuration_exec_path_test.cpp b/source/tests/metacall_configuration_exec_path_test/source/metacall_configuration_exec_path_test.cpp index 7458311c0..0219e58aa 100644 --- a/source/tests/metacall_configuration_exec_path_test/source/metacall_configuration_exec_path_test.cpp +++ b/source/tests/metacall_configuration_exec_path_test/source/metacall_configuration_exec_path_test.cpp @@ -49,7 +49,7 @@ TEST_F(metacall_configuration_exec_path_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Python hello_world: test")); + EXPECT_STREQ(metacall_value_to_string(ret), "Python hello_world: test"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp b/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp index 9257ec918..cd56aa446 100644 --- a/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp +++ b/source/tests/metacall_configuration_exec_relative_path_test/source/metacall_configuration_exec_relative_path_test.cpp @@ -49,7 +49,7 @@ TEST_F(metacall_configuration_exec_relative_path_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Python hello_world: test")); + EXPECT_STREQ(metacall_value_to_string(ret), "Python hello_world: test"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_cs_test/source/metacall_cs_test.cpp b/source/tests/metacall_cs_test/source/metacall_cs_test.cpp index 769382b15..799b24ec0 100644 --- a/source/tests/metacall_cs_test/source/metacall_cs_test.cpp +++ b/source/tests/metacall_cs_test/source/metacall_cs_test.cpp @@ -81,7 +81,7 @@ TEST_F(metacall_cs_test, Concat) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp((const char *)metacall_value_to_string(ret), "Hello World")); + EXPECT_STREQ((const char *)metacall_value_to_string(ret), "Hello World"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp b/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp index 59138c84e..30b2033cb 100644 --- a/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp +++ b/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp @@ -106,7 +106,7 @@ TEST_F(metacall_distributable_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello Universe")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello Universe"); metacall_value_destroy(ret); } @@ -143,7 +143,7 @@ TEST_F(metacall_distributable_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello meta-programmer!")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello meta-programmer!"); metacall_value_destroy(ret); @@ -193,7 +193,7 @@ TEST_F(metacall_distributable_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "abcdef")); + EXPECT_STREQ(metacall_value_to_string(ret), "abcdef"); metacall_value_destroy(ret); @@ -201,7 +201,7 @@ TEST_F(metacall_distributable_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "efg")); + EXPECT_STREQ(metacall_value_to_string(ret), "efg"); metacall_value_destroy(ret); } @@ -246,7 +246,7 @@ TEST_F(metacall_distributable_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello World")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello World"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp b/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp index b9555204a..0b8e2e2e8 100644 --- a/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp +++ b/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp @@ -123,7 +123,7 @@ TEST_F(metacall_ducktype_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_cast_string(&ret), "Hello Universe")); + EXPECT_STREQ(metacall_value_cast_string(&ret), "Hello Universe"); metacall_value_destroy(ret); @@ -209,7 +209,7 @@ TEST_F(metacall_ducktype_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_cast_string(&ret), "PepicoWalas")); + EXPECT_STREQ(metacall_value_cast_string(&ret), "PepicoWalas"); metacall_value_destroy(ret); metacall_value_destroy(args[0]); @@ -260,7 +260,7 @@ TEST_F(metacall_ducktype_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_cast_string(&ret), "Hello meta-programmer!")); + EXPECT_STREQ(metacall_value_cast_string(&ret), "Hello meta-programmer!"); metacall_value_destroy(ret); @@ -344,7 +344,7 @@ TEST_F(metacall_ducktype_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_cast_string(&ret), "abcdef")); + EXPECT_STREQ(metacall_value_cast_string(&ret), "abcdef"); metacall_value_destroy(ret); diff --git a/source/tests/metacall_function_test/source/metacall_function_test.cpp b/source/tests/metacall_function_test/source/metacall_function_test.cpp index 950bf6b1a..8b837151a 100644 --- a/source/tests/metacall_function_test/source/metacall_function_test.cpp +++ b/source/tests/metacall_function_test/source/metacall_function_test.cpp @@ -221,7 +221,7 @@ TEST_F(metacall_function_test, DefaultConstructor) EXPECT_EQ((enum metacall_value_id)METACALL_STRING, (enum metacall_value_id)metacall_value_id(ret)); - EXPECT_EQ((int)0, (int)strcmp("hello world", metacall_value_to_string(ret))); + EXPECT_STREQ("hello world", metacall_value_to_string(ret)); metacall_value_destroy(ret); diff --git a/source/tests/metacall_handle_get_test/source/metacall_handle_get_test.cpp b/source/tests/metacall_handle_get_test/source/metacall_handle_get_test.cpp index fff68579b..2e8013038 100644 --- a/source/tests/metacall_handle_get_test/source/metacall_handle_get_test.cpp +++ b/source/tests/metacall_handle_get_test/source/metacall_handle_get_test.cpp @@ -113,7 +113,7 @@ TEST_F(metacall_handle_get_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello from s1")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello from s1"); metacall_value_destroy(ret); @@ -135,7 +135,7 @@ TEST_F(metacall_handle_get_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello from s2")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello from s2"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_java_test/source/metacall_java_test.cpp b/source/tests/metacall_java_test/source/metacall_java_test.cpp index 996ff70ca..5eb6141cc 100644 --- a/source/tests/metacall_java_test/source/metacall_java_test.cpp +++ b/source/tests/metacall_java_test/source/metacall_java_test.cpp @@ -102,8 +102,8 @@ TEST_F(metacall_java_test, DefaultConstructor) { //GET ARRAYS void *str_test = metacall_class_static_get(myclass, "STRING_TEST_Arr"); void **str_test_arr = metacall_value_to_array(str_test); - ASSERT_EQ((int)0, (int)strcmp(metacall_value_to_string(str_test_arr[0]), "Hello")); - ASSERT_EQ((int)0, (int)strcmp(metacall_value_to_string(str_test_arr[1]), "world")); + ASSERT_STREQ(metacall_value_to_string(str_test_arr[0]), "Hello"); + ASSERT_STREQ(metacall_value_to_string(str_test_arr[1]), "world"); metacall_value_destroy(str_test); void *class_test = metacall_class_static_get(myclass, "CLASS_TEST_Arr"); diff --git a/source/tests/metacall_load_configuration_test/source/metacall_load_configuration_test.cpp b/source/tests/metacall_load_configuration_test/source/metacall_load_configuration_test.cpp index 5562783fa..21657b9c8 100644 --- a/source/tests/metacall_load_configuration_test/source/metacall_load_configuration_test.cpp +++ b/source/tests/metacall_load_configuration_test/source/metacall_load_configuration_test.cpp @@ -108,7 +108,7 @@ TEST_F(metacall_load_configuration_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello Universe")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello Universe"); metacall_value_destroy(ret); @@ -192,7 +192,7 @@ TEST_F(metacall_load_configuration_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello Universe")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello Universe"); metacall_value_destroy(ret); } @@ -225,7 +225,7 @@ TEST_F(metacall_load_configuration_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello meta-programmer!")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello meta-programmer!"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_map_await_test/source/metacall_map_await_test.cpp b/source/tests/metacall_map_await_test/source/metacall_map_await_test.cpp index 7c68df229..d3f1d4eb7 100644 --- a/source/tests/metacall_map_await_test/source/metacall_map_await_test.cpp +++ b/source/tests/metacall_map_await_test/source/metacall_map_await_test.cpp @@ -96,7 +96,7 @@ static void *hello_world_await_ok(void *result, void *data) fflush(stdout); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(result), "Hello World")); + EXPECT_STREQ(metacall_value_to_string(result), "Hello World"); ++success_callbacks; diff --git a/source/tests/metacall_map_test/source/metacall_map_test.cpp b/source/tests/metacall_map_test/source/metacall_map_test.cpp index 5f98a5a5f..84d641f4d 100644 --- a/source/tests/metacall_map_test/source/metacall_map_test.cpp +++ b/source/tests/metacall_map_test/source/metacall_map_test.cpp @@ -201,7 +201,7 @@ TEST_F(metacall_map_test, DefaultConstructor) ASSERT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "ACK: OK!")); + EXPECT_STREQ(metacall_value_to_string(ret), "ACK: OK!"); metacall_value_destroy(ret); */ diff --git a/source/tests/metacall_node_exception_test/source/metacall_node_exception_test.cpp b/source/tests/metacall_node_exception_test/source/metacall_node_exception_test.cpp index 9de810277..fd1c3b2e2 100644 --- a/source/tests/metacall_node_exception_test/source/metacall_node_exception_test.cpp +++ b/source/tests/metacall_node_exception_test/source/metacall_node_exception_test.cpp @@ -53,7 +53,7 @@ TEST_F(metacall_node_exception_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_error_from_value(ret, &ex)); - EXPECT_EQ((int)0, (int)strcmp("Yeet", ex.message)); + EXPECT_STREQ("Yeet", ex.message); metacall_value_destroy(ret); @@ -61,7 +61,7 @@ TEST_F(metacall_node_exception_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_error_from_value(ret, &ex)); - EXPECT_EQ((int)0, (int)strcmp("YeetThrown", ex.message)); + EXPECT_STREQ("YeetThrown", ex.message); metacall_value_destroy(ret); diff --git a/source/tests/metacall_node_extension_test/source/metacall_node_extension_test.cpp b/source/tests/metacall_node_extension_test/source/metacall_node_extension_test.cpp index 4e0986485..ef5fd6caf 100644 --- a/source/tests/metacall_node_extension_test/source/metacall_node_extension_test.cpp +++ b/source/tests/metacall_node_extension_test/source/metacall_node_extension_test.cpp @@ -52,7 +52,7 @@ TEST_F(metacall_node_extension_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp("world", metacall_value_to_string(ret))); + EXPECT_STREQ("world", metacall_value_to_string(ret)); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_node_port_test/source/metacall_node_port_test.cpp b/source/tests/metacall_node_port_test/source/metacall_node_port_test.cpp index 081bf8337..ab1d6df11 100644 --- a/source/tests/metacall_node_port_test/source/metacall_node_port_test.cpp +++ b/source/tests/metacall_node_port_test/source/metacall_node_port_test.cpp @@ -59,7 +59,7 @@ TEST_F(metacall_node_port_test, DefaultConstructor) struct await_data_type *await_data = static_cast<struct await_data_type *>(data); std::unique_lock<std::mutex> lock(await_data->m); const char *str = metacall_value_to_string(v); - EXPECT_EQ((int)0, (int)strcmp(str, "Tests passed without errors")); + EXPECT_STREQ(str, "Tests passed without errors"); await_data->c.notify_one(); return NULL; }; diff --git a/source/tests/metacall_python_dict_test/source/metacall_python_dict_test.cpp b/source/tests/metacall_python_dict_test/source/metacall_python_dict_test.cpp index cab84c549..f5db7671c 100644 --- a/source/tests/metacall_python_dict_test/source/metacall_python_dict_test.cpp +++ b/source/tests/metacall_python_dict_test/source/metacall_python_dict_test.cpp @@ -61,7 +61,7 @@ TEST_F(metacall_python_dict_test, DefaultConstructor) } else if (strcmp(key, "hello") == 0) { - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(array[1]), "world")); + EXPECT_STREQ(metacall_value_to_string(array[1]), "world"); } else if (strcmp(key, "efg") == 0) { @@ -134,14 +134,14 @@ TEST_F(metacall_python_dict_test, DefaultConstructor) char *ret_key0 = metacall_value_to_string(ret_pair0[0]); long ret_value0 = metacall_value_to_long(ret_pair0[1]); - EXPECT_EQ((int)0, (int)strcmp(ret_key0, "new")); + EXPECT_STREQ(ret_key0, "new"); EXPECT_EQ((long)5, (long)ret_value0); void **ret_pair1 = metacall_value_to_array(ret_map[1]); char *ret_key1 = metacall_value_to_string(ret_pair1[0]); long ret_value1 = metacall_value_to_long(ret_pair1[1]); - EXPECT_EQ((int)0, (int)strcmp(ret_key1, "whatever")); + EXPECT_STREQ(ret_key1, "whatever"); EXPECT_EQ((long)7, (long)ret_value1); metacall_value_destroy(ret); diff --git a/source/tests/metacall_python_exception_test/source/metacall_python_exception_test.cpp b/source/tests/metacall_python_exception_test/source/metacall_python_exception_test.cpp index 8d902ced5..14ec35d75 100644 --- a/source/tests/metacall_python_exception_test/source/metacall_python_exception_test.cpp +++ b/source/tests/metacall_python_exception_test/source/metacall_python_exception_test.cpp @@ -54,9 +54,9 @@ TEST_F(metacall_python_exception_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_error_from_value(ret, &ex)); - EXPECT_EQ((int)0, (int)strcmp("yeet", ex.message)); + EXPECT_STREQ("yeet", ex.message); - EXPECT_EQ((int)0, (int)strcmp("TypeError", ex.label)); + EXPECT_STREQ("TypeError", ex.label); metacall_value_destroy(ret); @@ -64,9 +64,9 @@ TEST_F(metacall_python_exception_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_error_from_value(ret, &ex)); - EXPECT_EQ((int)0, (int)strcmp("asdf", ex.message)); + EXPECT_STREQ("asdf", ex.message); - EXPECT_EQ((int)0, (int)strcmp("BaseException", ex.label)); + EXPECT_STREQ("BaseException", ex.label); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_python_loader_port_test/source/metacall_python_loader_port_test.cpp b/source/tests/metacall_python_loader_port_test/source/metacall_python_loader_port_test.cpp index 106797f36..ffa904326 100644 --- a/source/tests/metacall_python_loader_port_test/source/metacall_python_loader_port_test.cpp +++ b/source/tests/metacall_python_loader_port_test/source/metacall_python_loader_port_test.cpp @@ -37,7 +37,7 @@ void *callback_host(size_t argc, void *args[], void *data) printf("Host callback: %s\n", str); - EXPECT_EQ((int)0, (int)strcmp(str, "some text")); + EXPECT_STREQ(str, "some text"); return metacall_value_create_int(25); } @@ -86,7 +86,7 @@ TEST_F(metacall_python_loader_port_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_cast_string(&ret), "Hello meta-programmer!")); + EXPECT_STREQ(metacall_value_cast_string(&ret), "Hello meta-programmer!"); metacall_value_destroy(ret); diff --git a/source/tests/metacall_python_open_test/source/metacall_python_open_test.cpp b/source/tests/metacall_python_open_test/source/metacall_python_open_test.cpp index 3eda60fe5..0174eb61f 100644 --- a/source/tests/metacall_python_open_test/source/metacall_python_open_test.cpp +++ b/source/tests/metacall_python_open_test/source/metacall_python_open_test.cpp @@ -49,7 +49,7 @@ TEST_F(metacall_python_open_test, DefaultConstructor) const char *result = metacall_value_to_string(ret); - EXPECT_NE((int)0, (int)strcmp(result, "<html><head></head><body>Error</body></html>")); + EXPECT_STRNE(result, "<html><head></head><body>Error</body></html>"); metacall_value_destroy(ret); @@ -65,7 +65,7 @@ TEST_F(metacall_python_open_test, DefaultConstructor) const char *token = metacall_value_to_string(ret); - EXPECT_EQ((int)0, (int)strcmp(token, "eyJhbGciOiJIUzI1NiJ9.SGVsbG8gV29ybGQ.Iyc6PWVbK538giVdaInTeIO3jvvC1Vuy_czZUzoRRec")); + EXPECT_STREQ(token, "eyJhbGciOiJIUzI1NiJ9.SGVsbG8gV29ybGQ.Iyc6PWVbK538giVdaInTeIO3jvvC1Vuy_czZUzoRRec"); metacall_value_destroy(args[0]); diff --git a/source/tests/metacall_python_port_test/source/metacall_python_port_test.cpp b/source/tests/metacall_python_port_test/source/metacall_python_port_test.cpp index a86f7f111..7ebb7c236 100644 --- a/source/tests/metacall_python_port_test/source/metacall_python_port_test.cpp +++ b/source/tests/metacall_python_port_test/source/metacall_python_port_test.cpp @@ -46,7 +46,7 @@ TEST_F(metacall_python_port_test, DefaultConstructor) void *ret = metacallv("main", metacall_null_args); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Tests passed without errors")); + EXPECT_STREQ(metacall_value_to_string(ret), "Tests passed without errors"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_return_monad_test/source/metacall_return_monad_test.cpp b/source/tests/metacall_return_monad_test/source/metacall_return_monad_test.cpp index dfcf6e70c..5194d3ab8 100644 --- a/source/tests/metacall_return_monad_test/source/metacall_return_monad_test.cpp +++ b/source/tests/metacall_return_monad_test/source/metacall_return_monad_test.cpp @@ -78,7 +78,7 @@ TEST_F(metacall_return_monad_test, DefaultConstructor) EXPECT_EQ((enum metacall_value_id)METACALL_STRING, (enum metacall_value_id)metacall_value_id(ret)); - EXPECT_EQ((int)0, (int)strcmp("asd", metacall_value_to_string(ret))); + EXPECT_STREQ("asd", metacall_value_to_string(ret)); value_str = metacall_serialize(metacall_serial(), ret, &size, allocator); diff --git a/source/tests/metacall_ruby_parser_integration_test/source/metacall_ruby_parser_integration_test.cpp b/source/tests/metacall_ruby_parser_integration_test/source/metacall_ruby_parser_integration_test.cpp index b269fd9c2..0e38e65ac 100644 --- a/source/tests/metacall_ruby_parser_integration_test/source/metacall_ruby_parser_integration_test.cpp +++ b/source/tests/metacall_ruby_parser_integration_test/source/metacall_ruby_parser_integration_test.cpp @@ -74,7 +74,7 @@ TEST_F(metacall_ruby_parser_integration_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "call")); + EXPECT_STREQ(metacall_value_to_string(ret), "call"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_rust_load_from_package_dep_test/source/metacall_rust_load_from_package_dep_test.cpp b/source/tests/metacall_rust_load_from_package_dep_test/source/metacall_rust_load_from_package_dep_test.cpp index bc2d7930c..565883bc2 100644 --- a/source/tests/metacall_rust_load_from_package_dep_test/source/metacall_rust_load_from_package_dep_test.cpp +++ b/source/tests/metacall_rust_load_from_package_dep_test/source/metacall_rust_load_from_package_dep_test.cpp @@ -40,7 +40,7 @@ TEST_F(metacall_rust_load_from_package_dep_test, DefaultConstructor) const char *text = "{\"name\": \"John Doe\"}"; void *ret = metacall("compile", text); ASSERT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "\"John Doe\"")); + EXPECT_STREQ(metacall_value_to_string(ret), "\"John Doe\""); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp b/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp index 37f6394bb..cfb3b4995 100644 --- a/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp +++ b/source/tests/metacall_rust_load_from_package_test/source/metacall_rust_load_from_package_test.cpp @@ -93,7 +93,7 @@ TEST_F(metacall_rust_load_from_mem_test, DefaultConstructor) // void *ret = metacall("string_len", "Test String"); // EXPECT_EQ((long)11, (long)metacall_value_to_long(ret)); // ret = metacall("new_string", 123); - // EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "get number 123")); + // EXPECT_STREQ(metacall_value_to_string(ret), "get number 123"); // metacall_value_destroy(ret); // } diff --git a/source/tests/metacall_rust_test/source/metacall_rust_test.cpp b/source/tests/metacall_rust_test/source/metacall_rust_test.cpp index 85b9253da..55736c73e 100644 --- a/source/tests/metacall_rust_test/source/metacall_rust_test.cpp +++ b/source/tests/metacall_rust_test/source/metacall_rust_test.cpp @@ -94,13 +94,13 @@ TEST_F(metacall_rust_test, DefaultConstructor) // void *ret = metacall("string_len", "Test String"); // EXPECT_EQ((long)11, (long)metacall_value_to_long(ret)); // ret = metacall("new_string", 123); - // EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "get number 123")); + // EXPECT_STREQ(metacall_value_to_string(ret), "get number 123"); // metacall_value_destroy(ret); // } { void *ret = metacall("str_slice", "hellow"); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "hel")); + EXPECT_STREQ(metacall_value_to_string(ret), "hel"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_test/source/metacall_test.cpp b/source/tests/metacall_test/source/metacall_test.cpp index 3f250b3cd..ddbf10c03 100644 --- a/source/tests/metacall_test/source/metacall_test.cpp +++ b/source/tests/metacall_test/source/metacall_test.cpp @@ -216,7 +216,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello Universe")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello Universe"); metacall_value_destroy(ret); @@ -276,7 +276,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), web_content)); + EXPECT_STREQ(metacall_value_to_string(ret), web_content); metacall_value_destroy(ret); @@ -353,7 +353,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello meta-programmer!")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello meta-programmer!"); metacall_value_destroy(ret); @@ -420,7 +420,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "abcdef")); + EXPECT_STREQ(metacall_value_to_string(ret), "abcdef"); metacall_value_destroy(ret); @@ -428,7 +428,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "efg")); + EXPECT_STREQ(metacall_value_to_string(ret), "efg"); metacall_value_destroy(ret); } @@ -473,7 +473,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "Hello World")); + EXPECT_STREQ(metacall_value_to_string(ret), "Hello World"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_test/source/metacall_test_split.cpp b/source/tests/metacall_test/source/metacall_test_split.cpp index 49d0fc8f1..0a19bce6a 100644 --- a/source/tests/metacall_test/source/metacall_test_split.cpp +++ b/source/tests/metacall_test/source/metacall_test_split.cpp @@ -131,7 +131,7 @@ TEST_F(metacall_loader_test, Python) EXPECT_NE((value)NULL, (value)ret); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello Universe")); + EXPECT_STREQ(value_to_string(ret), "Hello Universe"); value_destroy(ret); } @@ -167,7 +167,7 @@ TEST_F(metacall_loader_test, Ruby) EXPECT_NE((value)NULL, (value)ret); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello meta-programmer!")); + EXPECT_STREQ(value_to_string(ret), "Hello meta-programmer!"); value_destroy(ret); } @@ -207,7 +207,7 @@ TEST_F(metacall_loader_test, JavascriptV8) EXPECT_NE((value)NULL, (value)ret); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(ret), "abcdef")); + EXPECT_STREQ(value_to_string(ret), "abcdef"); value_destroy(ret); } @@ -251,7 +251,7 @@ TEST_F(metacall_loader_test, Mock) EXPECT_NE((value)NULL, (value)ret); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello World")); + EXPECT_STREQ(value_to_string(ret), "Hello World"); value_destroy(ret); @@ -259,7 +259,7 @@ TEST_F(metacall_loader_test, Mock) EXPECT_NE((value)NULL, (value)ret); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello World")); + EXPECT_STREQ(value_to_string(ret), "Hello World"); value_destroy(ret); } diff --git a/source/tests/metacall_typescript_tsx_test/source/metacall_typescript_tsx_test.cpp b/source/tests/metacall_typescript_tsx_test/source/metacall_typescript_tsx_test.cpp index 16404c17d..52a406737 100644 --- a/source/tests/metacall_typescript_tsx_test/source/metacall_typescript_tsx_test.cpp +++ b/source/tests/metacall_typescript_tsx_test/source/metacall_typescript_tsx_test.cpp @@ -52,7 +52,7 @@ TEST_F(metacall_tsx_test, DefaultConstructor) EXPECT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((int)0, (int)strcmp(metacall_value_to_string(ret), "<h1 data-reactroot=\"\">Hello metaprogrammer</h1>")); + EXPECT_STREQ(metacall_value_to_string(ret), "<h1 data-reactroot=\"\">Hello metaprogrammer</h1>"); metacall_value_destroy(ret); } diff --git a/source/tests/metacall_version_test/source/metacall_version_test.cpp b/source/tests/metacall_version_test/source/metacall_version_test.cpp index b7023840b..ef703c79a 100644 --- a/source/tests/metacall_version_test/source/metacall_version_test.cpp +++ b/source/tests/metacall_version_test/source/metacall_version_test.cpp @@ -31,7 +31,7 @@ TEST_F(metacall_version_test, DefaultConstructor) { metacall_print_info(); - ASSERT_EQ((int)0, (int)strcmp(METACALL_VERSION, metacall_version_str())); + ASSERT_STREQ(METACALL_VERSION, metacall_version_str()); /* TODO: Test other version functions */ } diff --git a/source/tests/reflect_object_class_test/source/reflect_object_class_test.cpp b/source/tests/reflect_object_class_test/source/reflect_object_class_test.cpp index a0d7e0cc2..1abd68347 100644 --- a/source/tests/reflect_object_class_test/source/reflect_object_class_test.cpp +++ b/source/tests/reflect_object_class_test/source/reflect_object_class_test.cpp @@ -500,7 +500,7 @@ TEST_F(reflect_object_class_test, DefaultConstructor) ASSERT_NE((value)NULL, (value)ret); - ASSERT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello World")); + ASSERT_STREQ(value_to_string(ret), "Hello World"); value_type_destroy(ret); @@ -557,7 +557,7 @@ TEST_F(reflect_object_class_test, DefaultConstructor) ASSERT_NE((value)NULL, (value)ret); - ASSERT_EQ((int)0, (int)strcmp(value_to_string(ret), "Hello World")); + ASSERT_STREQ(value_to_string(ret), "Hello World"); value_type_destroy(ret); diff --git a/source/tests/serial_test/source/serial_test.cpp b/source/tests/serial_test/source/serial_test.cpp index 921a417bb..bf2d158ac 100644 --- a/source/tests/serial_test/source/serial_test.cpp +++ b/source/tests/serial_test/source/serial_test.cpp @@ -35,9 +35,9 @@ class serial_test : public testing::Test ASSERT_NE((serial)NULL, (serial)s); - EXPECT_EQ((int)0, (int)strcmp(name, serial_name(s))); + EXPECT_STREQ(name, serial_name(s)); - EXPECT_EQ((int)0, (int)strcmp(extension, serial_extension(s))); + EXPECT_STREQ(extension, serial_extension(s)); } const char *rapid_json_name() @@ -140,7 +140,7 @@ TEST_F(serial_test, DefaultConstructor) EXPECT_EQ((size_t)sizeof(value_list_str), (size_t)serialize_size); EXPECT_NE((char *)NULL, (char *)buffer); - EXPECT_EQ((int)0, (int)strcmp(buffer, value_list_str)); + EXPECT_STREQ(buffer, value_list_str); value_destroy(v); @@ -161,7 +161,7 @@ TEST_F(serial_test, DefaultConstructor) EXPECT_EQ((size_t)sizeof(value_map_str), (size_t)serialize_size); EXPECT_NE((value)NULL, (value)v); - EXPECT_EQ((int)0, (int)strcmp(buffer, value_map_str)); + EXPECT_STREQ(buffer, value_map_str); value *v_map = value_to_map(v); @@ -189,7 +189,7 @@ TEST_F(serial_test, DefaultConstructor) EXPECT_EQ((size_t)sizeof(json_empty_array), (size_t)serialize_size); EXPECT_NE((value)NULL, (value)v); - EXPECT_EQ((int)0, (int)strcmp(buffer, json_empty_array)); + EXPECT_STREQ(buffer, json_empty_array); value_destroy(v); @@ -206,7 +206,7 @@ TEST_F(serial_test, DefaultConstructor) EXPECT_NE((value *)NULL, (value *)v_array); EXPECT_EQ((type_id)TYPE_STRING, (type_id)value_type_id(v_array[0])); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(v_array[0]), "asdf")); + EXPECT_STREQ(value_to_string(v_array[0]), "asdf"); EXPECT_EQ((type_id)TYPE_INT, (type_id)value_type_id(v_array[1])); EXPECT_EQ((int)443, (int)value_to_int(v_array[1])); @@ -237,7 +237,7 @@ TEST_F(serial_test, DefaultConstructor) value *tupla = value_to_array(v_map[0]); EXPECT_EQ((type_id)TYPE_STRING, (type_id)value_type_id(tupla[0])); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(tupla[0]), "abc")); + EXPECT_STREQ(value_to_string(tupla[0]), "abc"); EXPECT_EQ((type_id)TYPE_FLOAT, (type_id)value_type_id(tupla[1])); EXPECT_EQ((float)9.9f, (float)value_to_float(tupla[1])); @@ -250,7 +250,7 @@ TEST_F(serial_test, DefaultConstructor) tupla = value_to_array(v_map[1]); EXPECT_EQ((type_id)TYPE_STRING, (type_id)value_type_id(tupla[0])); - EXPECT_EQ((int)0, (int)strcmp(value_to_string(tupla[0]), "cde")); + EXPECT_STREQ(value_to_string(tupla[0]), "cde"); EXPECT_EQ((type_id)TYPE_FLOAT, (type_id)value_type_id(tupla[1])); EXPECT_EQ((float)1.5f, (float)value_to_float(tupla[1])); From 7f59fe8db76b658ae143630347b16d428c495fd3 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Sat, 20 Sep 2025 17:12:03 +0200 Subject: [PATCH 100/109] Add base for cxx port. --- source/ports/CMakeLists.txt | 2 +- source/ports/cxx_port/CMakeLists.txt | 111 ++--- .../cxx_port/include/metacall/metacall.hpp | 414 +++++++++++++++++- .../cxx_port/inline/metacall/metacall.inl | 2 +- source/tests/CMakeLists.txt | 1 + .../metacall_cxx_port_test/CMakeLists.txt | 151 +++++++ .../metacall_cxx_port_test/source/main.cpp | 28 ++ .../source/metacall_cxx_port_test.cpp | 96 ++++ 8 files changed, 722 insertions(+), 83 deletions(-) create mode 100644 source/tests/metacall_cxx_port_test/CMakeLists.txt create mode 100644 source/tests/metacall_cxx_port_test/source/main.cpp create mode 100644 source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp diff --git a/source/ports/CMakeLists.txt b/source/ports/CMakeLists.txt index cc73de928..e70bb151d 100644 --- a/source/ports/CMakeLists.txt +++ b/source/ports/CMakeLists.txt @@ -28,7 +28,7 @@ endif() # Project options option(OPTION_BUILD_PORTS_CS "Build C# port." OFF) -option(OPTION_BUILD_PORTS_CXX "Build C++ port." OFF) +option(OPTION_BUILD_PORTS_CXX "Build C++ port." ON) option(OPTION_BUILD_PORTS_D "Build D port." OFF) option(OPTION_BUILD_PORTS_GO "Build Go port." OFF) option(OPTION_BUILD_PORTS_JAVA "Build Java port." OFF) diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index bc450a068..88ce40460 100644 --- a/source/ports/cxx_port/CMakeLists.txt +++ b/source/ports/cxx_port/CMakeLists.txt @@ -9,17 +9,14 @@ endif() # Target name set(target cxx_port) -string(TOLOWER ${META_PROJECT_NAME} target_name) - -set(target_export "${META_PROJECT_NAME}-cxx") # Exit here if required dependencies are not met message(STATUS "Port ${target}") # Set API export file and macro -string(TOUPPER ${target_name} target_name_upper) -set(export_file "include/${target_name}/${target_name}_api.hpp") -set(export_macro "${target_name_upper}_API") +string(TOUPPER ${target} target_upper) +set(export_file "include/${target}/${target}_api.h") +set(export_macro "${target_upper}_API") # # Compiler warnings @@ -37,8 +34,8 @@ include(SecurityFlags) # Sources # -set(inline_path "${CMAKE_CURRENT_SOURCE_DIR}/inline/${target_name}") -set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target_name}") +set(inline_path "${CMAKE_CURRENT_SOURCE_DIR}/inline/metacall") +set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/metacall") set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(inlines @@ -79,7 +76,7 @@ add_library(${target} add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) # Export library for downstream projects -export(TARGETS ${target} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target_name}/${target_export}-export.cmake) +export(TARGETS ${target} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake) # Create API export header generate_export_header(${target} @@ -100,12 +97,16 @@ set_target_properties(${target} # # Include directories # + target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR}/source/include ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include + + ${PROJECT_BINARY_DIR}/source/inline ${CMAKE_CURRENT_SOURCE_DIR}/inline + ${CMAKE_CURRENT_BINARY_DIR}/inline PUBLIC ${DEFAULT_INCLUDE_DIRECTORIES} @@ -114,6 +115,26 @@ target_include_directories(${target} $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> + + + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inline> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/inline> + $<INSTALL_INTERFACE:inline> +) + +# +# Libraries +# + +target_link_libraries(${target} + PRIVATE + ${META_PROJECT_NAME}::metacall + + PUBLIC + ${DEFAULT_LIBRARIES} + + INTERFACE + ${META_PROJECT_NAME}::metacall ) # @@ -122,9 +143,10 @@ target_include_directories(${target} target_compile_definitions(${target} PRIVATE + ${target_upper}_EXPORTS # Export API PUBLIC - $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:${target_name_upper}_STATIC_DEFINE> + $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:${target_upper}_STATIC_DEFINE> ${DEFAULT_COMPILE_DEFINITIONS} INTERFACE @@ -155,72 +177,3 @@ target_link_options(${target} INTERFACE ) - -# -# Deployment -# - -# Library -install(TARGETS ${target} - EXPORT "${target_export}-export" COMPONENT dev - RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT runtime - LIBRARY DESTINATION ${INSTALL_SHARED} COMPONENT runtime - ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT dev -) - -# Inline files -install(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/inline/${target_name} DESTINATION ${INSTALL_INCLUDE} - COMPONENT dev -) - -# Header files -install(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/include/${target_name} DESTINATION ${INSTALL_INCLUDE} - COMPONENT dev -) - -# Generated header files -install(DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}/include/${target_name} DESTINATION ${INSTALL_INCLUDE} - COMPONENT dev -) - -# CMake config -install(EXPORT ${target_export}-export - NAMESPACE ${META_PROJECT_NAME}:: - DESTINATION ${INSTALL_CMAKE}/${target_name} - COMPONENT dev -) - -# TODO - -# # -# # Configure test -# # - -# set(metacall_cxx_test "${target}_test") -# set(metacall_cxx_test_path "${CMAKE_CURRENT_BINARY_DIR}/${metacall_cxx_test}.cpp") - -# # -# # Define test -# # - -# add_test(NAME ${metacall_cxx_test} -# COMMAND $<TARGET_FILE:${metacall_cxx_test}> -# ) - -# # -# # Define test labels -# # - -# set_property(TEST ${metacall_cxx_test} -# PROPERTY LABELS ${metacall_cxx_test} -# ) - -# include(TestEnvironmentVariables) - -# test_environment_variables(${metacall_cxx_test} -# "" -# ${TESTS_ENVIRONMENT_VARIABLES} -# ) diff --git a/source/ports/cxx_port/include/metacall/metacall.hpp b/source/ports/cxx_port/include/metacall/metacall.hpp index 7995efa3e..83540d66e 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -23,17 +23,427 @@ /* -- Headers -- */ -#include <metacall/metacall_api.hpp> - +#include <cstring> +#include <memory> +#include <stdexcept> #include <string> +#include <unordered_map> +#include <vector> namespace metacall { +#include <metacall/metacall.h> + +class value_base +{ +public: + // Non-copyable, but movable + value_base(const value_base &) = delete; + value_base &operator=(const value_base &) = delete; + + value_base(value_base &&) noexcept = default; + value_base &operator=(value_base &&) noexcept = default; + + // Access the raw value + void *to_raw() const + { + return value_ptr.get(); + } + +protected: + std::unique_ptr<void, void (*)(void *)> value_ptr; + + explicit value_base(void *value_ptr, void (*destructor)(void *) = &noop_destructor) : + // TODO: &metacall_value_destroy + value_ptr(value_ptr, destructor) + { + } + + static void noop_destructor(void *) {} +}; + +template <typename T> +class METACALL_API value : public value_base +{ +public: + explicit value(const T &v) : + value_base(create(v)) + { + if (value_ptr == nullptr) + { + throw std::runtime_error("Failed to create MetaCall value"); + } + } + + explicit value(void *value_ptr) : + value_base(value_ptr, &value_base::noop_destructor) + { + if (metacall_value_id(value_ptr) != id()) + { + throw std::runtime_error("Failed to create MetaCall value, the received MetaCall value type does not match with the value class type"); + } + } + + T to_value() const + { + throw std::runtime_error("Unsupported MetaCall value"); + } + +private: + // Type-specific creation (calls specialized version below) + static void *create(const T &v); + + // Type-specific type id + static enum metacall_value_id id(); +}; + +template <> +inline void *value<bool>::create(const bool &v) +{ + return metacall_value_create_bool(v); +} + +template <> +inline enum metacall_value_id value<bool>::id() +{ + return METACALL_BOOL; +} + +template <> +inline bool value<bool>::to_value() const +{ + return metacall_value_to_bool(value_ptr.get()); +} + +template <> +inline void *value<char>::create(const char &v) +{ + return metacall_value_create_char(v); +} + +template <> +inline enum metacall_value_id value<char>::id() +{ + return METACALL_CHAR; +} + +template <> +inline char value<char>::to_value() const +{ + return metacall_value_to_char(value_ptr.get()); +} + +template <> +inline void *value<short>::create(const short &v) +{ + return metacall_value_create_short(v); +} + +template <> +inline enum metacall_value_id value<short>::id() +{ + return METACALL_SHORT; +} + +template <> +inline short value<short>::to_value() const +{ + return metacall_value_to_short(value_ptr.get()); +} + +template <> +inline void *value<int>::create(const int &v) +{ + return metacall_value_create_int(v); +} + +template <> +inline enum metacall_value_id value<int>::id() +{ + return METACALL_INT; +} + +template <> +inline int value<int>::to_value() const +{ + return metacall_value_to_int(value_ptr.get()); +} + +template <> +inline void *value<long>::create(const long &v) +{ + return metacall_value_create_long(v); +} + +template <> +inline enum metacall_value_id value<long>::id() +{ + return METACALL_LONG; +} + +template <> +inline long value<long>::to_value() const +{ + return metacall_value_to_long(value_ptr.get()); +} + +template <> +inline void *value<float>::create(const float &v) +{ + return metacall_value_create_float(v); +} + +template <> +inline enum metacall_value_id value<float>::id() +{ + return METACALL_FLOAT; +} + +template <> +inline float value<float>::to_value() const +{ + return metacall_value_to_float(value_ptr.get()); +} + +template <> +inline void *value<double>::create(const double &v) +{ + return metacall_value_create_double(v); +} + +template <> +inline enum metacall_value_id value<double>::id() +{ + return METACALL_DOUBLE; +} + +template <> +inline double value<double>::to_value() const +{ + return metacall_value_to_double(value_ptr.get()); +} + +template <> +inline void *value<std::string>::create(const std::string &v) +{ + return metacall_value_create_string(v.c_str(), v.size()); +} + +template <> +inline enum metacall_value_id value<std::string>::id() +{ + return METACALL_STRING; +} + +template <> +inline std::string value<std::string>::to_value() const +{ + return metacall_value_to_string(value_ptr.get()); +} + +template <> +inline void *value<const char *>::create(const char *const &v) +{ + return metacall_value_create_string(v, std::strlen(v)); +} + +template <> +inline enum metacall_value_id value<const char *>::id() +{ + return METACALL_STRING; +} + +template <> +inline const char *value<const char *>::to_value() const +{ + return metacall_value_to_string(value_ptr.get()); +} + +template <> +inline void *value<std::vector<char>>::create(const std::vector<char> &v) +{ + return metacall_value_create_buffer(v.data(), v.size()); +} + +template <> +inline enum metacall_value_id value<std::vector<char>>::id() +{ + return METACALL_BUFFER; +} + +template <> +inline std::vector<char> value<std::vector<char>>::to_value() const +{ + void *ptr = value_ptr.get(); + char *buffer = static_cast<char *>(metacall_value_to_buffer(ptr)); + std::vector<char> buffer_vector(buffer, buffer + metacall_value_count(ptr)); + + return buffer_vector; +} + +template <> +inline void *value<std::vector<unsigned char>>::create(const std::vector<unsigned char> &v) +{ + return metacall_value_create_buffer(v.data(), v.size()); +} + +template <> +inline enum metacall_value_id value<std::vector<unsigned char>>::id() +{ + return METACALL_BUFFER; +} + +template <> +inline std::vector<unsigned char> value<std::vector<unsigned char>>::to_value() const +{ + void *ptr = value_ptr.get(); + unsigned char *buffer = static_cast<unsigned char *>(metacall_value_to_buffer(ptr)); + std::vector<unsigned char> buffer_vector(buffer, buffer + metacall_value_count(ptr)); + + return buffer_vector; +} + +template <> +inline void *value<void *>::create(void *const &v) +{ + return metacall_value_create_ptr(v); +} + +template <> +inline enum metacall_value_id value<void *>::id() +{ + return METACALL_PTR; +} + +template <> +inline void *value<void *>::to_value() const +{ + return metacall_value_to_ptr(value_ptr.get()); +} + +template <> +inline void *value<std::nullptr_t>::create(const std::nullptr_t &) +{ + return metacall_value_create_null(); +} + +template <> +inline enum metacall_value_id value<std::nullptr_t>::id() +{ + return METACALL_NULL; +} + +template <> +inline std::nullptr_t value<std::nullptr_t>::to_value() const +{ + return nullptr; +} + +// TODO: Array, Map, Future, Function, Class, Object, Exception, Throwable... + +template <typename K, typename V> +class METACALL_API map : public value_base +{ +public: + using pair_type = std::pair<K, V>; + using pair_value_type = std::pair<value<K>, value<V>>; + + map(std::initializer_list<pair_type> list) : + value_base(metacall_value_create_map(NULL, list.size())) + { + if (value_ptr == nullptr) + { + throw std::runtime_error("Failed to create MetaCall map value"); + } + + void **map_array = metacall_value_to_map(value_ptr.get()); + size_t index = 0; + + for (const auto &pair : list) + { + void *tuple = metacall_value_create_array(nullptr, 2); + void **tuple_array = metacall_value_to_array(tuple); + + // Create the pair + auto value_pair = std::make_pair(value<K>(pair.first), value<V>(pair.second)); + + // Insert into metacall value map + tuple_array[0] = value_pair.first.to_raw(); + tuple_array[1] = value_pair.second.to_raw(); + + map_array[index++] = tuple; + + // Store into the map + m.emplace(pair.first, std::move(value_pair)); + } + } + + explicit map(void *value_ptr) : + value_base(value_ptr, &value_base::noop_destructor) + { + if (metacall_value_id(value_ptr) != METACALL_MAP) + { + throw std::runtime_error("MetaCall map initialized with a MetaCall value which is not of type map"); + } + + rehash(); + } + + void rehash() + { + void *ptr = value_ptr.get(); + void **map_array = metacall_value_to_map(ptr); + const size_t size = metacall_value_count(ptr); + + m.clear(); + + for (size_t index = 0; index < size; ++index) + { + void **tuple_array = metacall_value_to_array(map_array[index]); + + // Create the values + auto pair = std::make_pair(value<K>(tuple_array[0]), value<V>(tuple_array[1])); + + // Store into the map + m.emplace(pair.first.to_value(), std::move(pair)); + } + } + + V operator[](const K &key) const + { + return m.at(key).second.to_value(); + } + +private: + /* + // Case 1: value is value_base (e.g. nested metacall map value) + template <typename T> + static typename std::enable_if<std::is_base_of<value_base, T>::value, value<T>>::type + wrap_value(const T &v) + { + return const_cast<T &>(v); + } + + // Case 2: value is a plain type + template <typename T> + static typename std::enable_if<!std::is_base_of<value_base, T>::value, value<T>>::type + wrap_value(const T &v) + { + value<T> val(v); + return val; + } + */ + + std::unordered_map<K, pair_value_type> m; +}; + template <typename... Ts> METACALL_API int metacall(std::string name, Ts... ts); } /* namespace metacall */ +// TODO: Move everything to metacall.inl + #include <metacall/metacall.inl> #endif /* METACALL_HPP */ diff --git a/source/ports/cxx_port/inline/metacall/metacall.inl b/source/ports/cxx_port/inline/metacall/metacall.inl index 7789dff86..8223b5be0 100644 --- a/source/ports/cxx_port/inline/metacall/metacall.inl +++ b/source/ports/cxx_port/inline/metacall/metacall.inl @@ -23,7 +23,7 @@ /* -- Headers -- */ -#include <metacall/metacall_api.hpp> +#include <metacall/metacall_api.h> #include <string> diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 6e6ad2ffc..2f2e6bb89 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -246,3 +246,4 @@ add_subdirectory(metacall_cli_core_plugin_test) add_subdirectory(metacall_cli_core_plugin_await_test) add_subdirectory(metacall_backtrace_plugin_test) add_subdirectory(metacall_sandbox_plugin_test) +add_subdirectory(metacall_cxx_port_test) diff --git a/source/tests/metacall_cxx_port_test/CMakeLists.txt b/source/tests/metacall_cxx_port_test/CMakeLists.txt new file mode 100644 index 000000000..1a4b07292 --- /dev/null +++ b/source/tests/metacall_cxx_port_test/CMakeLists.txt @@ -0,0 +1,151 @@ +# Check if this loader is enabled +if(NOT OPTION_BUILD_PORTS OR NOT OPTION_BUILD_PORTS_CXX) + return() +endif() + +# +# Executable name and options +# + +# Target name +set(target metacall-cxx-port-test) +message(STATUS "Test ${target}") + +# +# Compiler warnings +# + +include(Warnings) + +# +# Compiler security +# + +include(SecurityFlags) + +# +# Sources +# + +set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") +set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") + +set(sources + ${source_path}/main.cpp + ${source_path}/metacall_cxx_port_test.cpp +) + +# Group source files +set(header_group "Header Files (API)") +set(source_group "Source Files") +source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" + ${header_group} ${headers}) +source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" + ${source_group} ${sources}) + +# +# Create executable +# + +# Build executable +add_executable(${target} + ${sources} +) + +# Create namespaced alias +add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) + +# +# Project options +# + +set_target_properties(${target} + PROPERTIES + ${DEFAULT_PROJECT_OPTIONS} + FOLDER "${IDE_FOLDER}" +) + +# +# Include directories +# + +target_include_directories(${target} + PRIVATE + ${DEFAULT_INCLUDE_DIRECTORIES} + ${PROJECT_BINARY_DIR}/source/include +) + +# +# Libraries +# + +target_link_libraries(${target} + PRIVATE + ${DEFAULT_LIBRARIES} + + GTest + + ${META_PROJECT_NAME}::cxx_port +) + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + ${DEFAULT_COMPILE_DEFINITIONS} + + LIBFFI_INCLUDE_DIR="${LIBFFI_INCLUDE_DIR}" + LIBFFI_LIBRARY="${LIBFFI_LIBRARY}" +) + +# +# Compile options +# + +target_compile_options(${target} + PRIVATE + ${DEFAULT_COMPILE_OPTIONS} +) + +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + +# +# Linker options +# + +target_link_options(${target} + PRIVATE + ${DEFAULT_LINKER_OPTIONS} +) + +# +# Define test +# + +add_test(NAME ${target} + COMMAND $<TARGET_FILE:${target}> +) + +# +# Define test properties +# + +set_property(TEST ${target} + PROPERTY LABELS ${target} +) + +include(TestEnvironmentVariables) + +test_environment_variables(${target} + "" + ${TESTS_ENVIRONMENT_VARIABLES} +) diff --git a/source/tests/metacall_cxx_port_test/source/main.cpp b/source/tests/metacall_cxx_port_test/source/main.cpp new file mode 100644 index 000000000..37d4adc23 --- /dev/null +++ b/source/tests/metacall_cxx_port_test/source/main.cpp @@ -0,0 +1,28 @@ +/* + * Loader Library by Parra Studios + * A plugin for loading ruby code at run-time into a process. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <gtest/gtest.h> + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp new file mode 100644 index 000000000..75f06a44e --- /dev/null +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -0,0 +1,96 @@ +/* + * Loader Library by Parra Studios + * A plugin for loading ruby code at run-time into a process. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <gtest/gtest.h> + +#include <metacall/metacall.hpp> + +using namespace metacall; + +class metacall_cxx_port_test : public testing::Test +{ +protected: +}; + +void *cxx_map_test(size_t argc, void *args[], void *data) +{ + map<std::string, float> m(args[0]); + + (void)argc; + (void)data; + + EXPECT_EQ((float)m["hello"], (float)3.0f); + EXPECT_EQ((float)m["world"], (float)4.0f); + + printf("hello => %f\n", m["hello"]); + printf("world => %f\n", m["world"]); + fflush(stdout); + + return metacall_value_create_null(); +} + +TEST_F(metacall_cxx_port_test, DefaultConstructor) +{ + ASSERT_EQ((int)0, (int)metacall_initialize()); + + { + map<std::string, float> m = { + { "hello", 3.0f }, + { "world", 4.0f } + }; + + void *args[] = { + m.to_raw() + }; + + metacall_register("cxx_map_test", cxx_map_test, NULL, METACALL_NULL, 1, METACALL_MAP); + + void *ret = metacallv_s("cxx_map_test", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + } + + /* Print inspect information */ + { + size_t size = 0; + + struct metacall_allocator_std_type std_ctx = { &std::malloc, &std::realloc, &std::free }; + + void *allocator = metacall_allocator_create(METACALL_ALLOCATOR_STD, (void *)&std_ctx); + + char *inspect_str = metacall_inspect(&size, allocator); + + EXPECT_NE((char *)NULL, (char *)inspect_str); + + EXPECT_GT((size_t)size, (size_t)0); + + std::cout << inspect_str << std::endl; + + metacall_allocator_free(allocator, inspect_str); + + metacall_allocator_destroy(allocator); + } + + metacall_destroy(); +} From 90f20b973e21342bc7a688b4564bfb0c99ae7143 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 24 Sep 2025 15:58:12 +0200 Subject: [PATCH 101/109] Solve issues with ownership in cxx port. --- source/ports/cxx_port/CMakeLists.txt | 16 ++++++++ .../cxx_port/include/metacall/metacall.hpp | 13 +++---- .../source/metacall_cxx_port_test.cpp | 39 +++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index 88ce40460..22fbea19f 100644 --- a/source/ports/cxx_port/CMakeLists.txt +++ b/source/ports/cxx_port/CMakeLists.txt @@ -177,3 +177,19 @@ target_link_options(${target} INTERFACE ) + +# +# Deployment +# + +# Header files +install(DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR}/include/${target} DESTINATION ${INSTALL_INCLUDE} + COMPONENT dev +) + +# Inline files +install(DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR}/inline/${target} DESTINATION ${INSTALL_INCLUDE} + COMPONENT dev +) diff --git a/source/ports/cxx_port/include/metacall/metacall.hpp b/source/ports/cxx_port/include/metacall/metacall.hpp index 83540d66e..afecc0fa6 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -53,11 +53,8 @@ class value_base protected: std::unique_ptr<void, void (*)(void *)> value_ptr; - explicit value_base(void *value_ptr, void (*destructor)(void *) = &noop_destructor) : - // TODO: &metacall_value_destroy - value_ptr(value_ptr, destructor) - { - } + explicit value_base(void *value_ptr, void (*destructor)(void *) = &metacall_value_destroy) : + value_ptr(value_ptr, destructor) {} static void noop_destructor(void *) {} }; @@ -66,8 +63,8 @@ template <typename T> class METACALL_API value : public value_base { public: - explicit value(const T &v) : - value_base(create(v)) + explicit value(const T &v, void (*destructor)(void *) = &metacall_value_destroy) : + value_base(create(v), destructor) { if (value_ptr == nullptr) { @@ -365,7 +362,7 @@ class METACALL_API map : public value_base void **tuple_array = metacall_value_to_array(tuple); // Create the pair - auto value_pair = std::make_pair(value<K>(pair.first), value<V>(pair.second)); + auto value_pair = std::make_pair(value<K>(pair.first, &value_base::noop_destructor), value<V>(pair.second, &value_base::noop_destructor)); // Insert into metacall value map tuple_array[0] = value_pair.first.to_raw(); diff --git a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp index 75f06a44e..72912ecf5 100644 --- a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -46,6 +46,23 @@ void *cxx_map_test(size_t argc, void *args[], void *data) return metacall_value_create_null(); } +void *cxx_recursive_map_test(size_t argc, void *args[], void *data) +{ + map<std::string, float> m(args[0]); + + (void)argc; + (void)data; + + EXPECT_EQ((float)m["hello"], (float)3.0f); + EXPECT_EQ((float)m["world"], (float)4.0f); + + printf("hello => %f\n", m["hello"]); + printf("world => %f\n", m["world"]); + fflush(stdout); + + return metacall_value_create_null(); +} + TEST_F(metacall_cxx_port_test, DefaultConstructor) { ASSERT_EQ((int)0, (int)metacall_initialize()); @@ -71,6 +88,28 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) metacall_value_destroy(ret); } + /* + { + map<std::string, map<std::string, float>> m = { + { "hello", { "world", 4.0f } }, + }; + + void *args[] = { + m.to_raw() + }; + + metacall_register("cxx_recursive_map_test", cxx_recursive_map_test, NULL, METACALL_NULL, 1, METACALL_MAP); + + void *ret = metacallv_s("cxx_recursive_map_test", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + } + */ + /* Print inspect information */ { size_t size = 0; From 182a757139b9084c404b06824357c581ecff56be Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 24 Sep 2025 18:32:57 +0200 Subject: [PATCH 102/109] Separated CI of rust into test and build. --- .github/workflows/release-rust.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 9ef5e2ec1..bc58a5915 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -35,16 +35,20 @@ jobs: - name: Install MetaCall Windows if: matrix.os == 'windows-latest' run: powershell -NoProfile -ExecutionPolicy Unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/metacall/install/master/install.ps1')))" + - name: Install Rust uses: actions-rs/toolchain@v1 with: toolchain: stable override: true - - name: Build and Test the Rust Port + + - name: Build Test the Rust Port working-directory: source/ports/rs_port - run: | - cargo build --verbose - cargo test --verbose + run: cargo build --verbose + + - name: Test the Rust Port + working-directory: source/ports/rs_port + run: cargo test --verbose release: name: Release Rust Port From 680b6bf7a4e415df9a0d8452b83972b9d2966fbb Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 24 Sep 2025 18:41:33 +0200 Subject: [PATCH 103/109] Remove version from rs_ports dependency. --- source/ports/rs_port/Cargo.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index c0e51713a..4ed8cee59 100644 --- a/source/ports/rs_port/Cargo.toml +++ b/source/ports/rs_port/Cargo.toml @@ -17,7 +17,13 @@ name = "metacall" path = "src/lib.rs" [dependencies] -metacall-inline = { path = "./inline", version = "0.2.0" } +metacall-inline = { path = "./inline" } [build-dependencies] -metacall-sys = { path = "./sys", version = "0.1.2" } +metacall-sys = { path = "./sys" } + +[workspace] +members = [ + "inline", + "sys", +] From 5d7c589784e3363b8507b629052a3ff7645806c1 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Tue, 30 Sep 2025 22:27:29 +0200 Subject: [PATCH 104/109] Improve few issues in c++ port. --- .github/workflows/release-rust.yml | 2 +- source/ports/cxx_port/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index bc58a5915..d2a0c31a4 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -42,7 +42,7 @@ jobs: toolchain: stable override: true - - name: Build Test the Rust Port + - name: Build the Rust Port working-directory: source/ports/rs_port run: cargo build --verbose diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index 22fbea19f..e3e79398a 100644 --- a/source/ports/cxx_port/CMakeLists.txt +++ b/source/ports/cxx_port/CMakeLists.txt @@ -184,12 +184,12 @@ target_link_options(${target} # Header files install(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/include/${target} DESTINATION ${INSTALL_INCLUDE} + ${CMAKE_CURRENT_SOURCE_DIR}/include/metacall DESTINATION ${INSTALL_INCLUDE} COMPONENT dev ) # Inline files install(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/inline/${target} DESTINATION ${INSTALL_INCLUDE} + ${CMAKE_CURRENT_SOURCE_DIR}/inline/metacall DESTINATION ${INSTALL_INCLUDE} COMPONENT dev ) From f3433115132cb9b2a8774c0ee5d3db5cc5c9b96c Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Wed, 1 Oct 2025 19:02:20 +0200 Subject: [PATCH 105/109] Improve cxx port. --- .../cxx_port/include/metacall/metacall.hpp | 37 ++++++------------- .../source/metacall_cxx_port_test.cpp | 14 ++++--- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/source/ports/cxx_port/include/metacall/metacall.hpp b/source/ports/cxx_port/include/metacall/metacall.hpp index afecc0fa6..d92a81638 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -336,7 +336,7 @@ inline std::nullptr_t value<std::nullptr_t>::to_value() const return nullptr; } -// TODO: Array, Map, Future, Function, Class, Object, Exception, Throwable... +// TODO: Future, Function, Class, Object, Exception, Throwable... template <typename K, typename V> class METACALL_API map : public value_base @@ -386,6 +386,17 @@ class METACALL_API map : public value_base rehash(); } + V operator[](const K &key) const + { + return m.at(key).second.to_value(); + } + + static enum metacall_value_id id() + { + return METACALL_MAP; + } + +protected: void rehash() { void *ptr = value_ptr.get(); @@ -406,31 +417,7 @@ class METACALL_API map : public value_base } } - V operator[](const K &key) const - { - return m.at(key).second.to_value(); - } - private: - /* - // Case 1: value is value_base (e.g. nested metacall map value) - template <typename T> - static typename std::enable_if<std::is_base_of<value_base, T>::value, value<T>>::type - wrap_value(const T &v) - { - return const_cast<T &>(v); - } - - // Case 2: value is a plain type - template <typename T> - static typename std::enable_if<!std::is_base_of<value_base, T>::value, value<T>>::type - wrap_value(const T &v) - { - value<T> val(v); - return val; - } - */ - std::unordered_map<K, pair_value_type> m; }; diff --git a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp index 72912ecf5..6865b258f 100644 --- a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -46,22 +46,23 @@ void *cxx_map_test(size_t argc, void *args[], void *data) return metacall_value_create_null(); } +// TODO: +/* void *cxx_recursive_map_test(size_t argc, void *args[], void *data) { - map<std::string, float> m(args[0]); + map<std::string, map<std::string, float>> m(args[0]); (void)argc; (void)data; - EXPECT_EQ((float)m["hello"], (float)3.0f); - EXPECT_EQ((float)m["world"], (float)4.0f); + EXPECT_EQ((float)m["hello"]["world"], (float)4.0f); - printf("hello => %f\n", m["hello"]); - printf("world => %f\n", m["world"]); + printf("hello => %f\n", m["hello"]["world"]); fflush(stdout); return metacall_value_create_null(); } +*/ TEST_F(metacall_cxx_port_test, DefaultConstructor) { @@ -88,10 +89,11 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) metacall_value_destroy(ret); } + // TODO: /* { map<std::string, map<std::string, float>> m = { - { "hello", { "world", 4.0f } }, + { "hello", { "world", 4.0f } } }; void *args[] = { From b4d673059147f11fbb917c2876ad8dd66fc071dd Mon Sep 17 00:00:00 2001 From: Thomas <thomas.gummerson@piql.com> Date: Wed, 1 Oct 2025 19:23:13 +0200 Subject: [PATCH 106/109] Reimplement and bugfix environment_variable_path_create, portability_path_get_name, portability_path_get_name_canonical (#580) - Get rid of some buffer overruns - make more functions return more sensible things on NULL arguments - properly DOCUMENT each function - Add const type qualifiers where applicable - Replace some string functions and loops with memcpy --- .../environment/environment_variable_path.h | 26 ++- .../source/environment_variable_path.c | 69 +++----- .../include/portability/portability_path.h | 50 +++++- source/portability/source/portability_path.c | 156 ++++++++---------- .../source/portability_path_test.cpp | 55 ++++++ 5 files changed, 213 insertions(+), 143 deletions(-) diff --git a/source/environment/include/environment/environment_variable_path.h b/source/environment/include/environment/environment_variable_path.h index d5492d8f6..58b8c2047 100644 --- a/source/environment/include/environment/environment_variable_path.h +++ b/source/environment/include/environment/environment_variable_path.h @@ -52,7 +52,31 @@ extern "C" { /* -- Methods -- */ -ENVIRONMENT_API char *environment_variable_path_create(const char *name, const char *default_path, size_t default_path_size, size_t *env_size); +/** + * @brief + * If the value of `name` exists as an environment variable, return a live string of its value, otherwise return a live value of `default_path` or "/". + * + * `name` should not be `NULL`. + * + * If `default_path` is not `NULL`, `default_path_size` must be set to <= the length (including 0-terminator) of the `default_path` string. + * + * If `env_size` is not `NULL`, the length (including 0-terminator) of the returned string will be set to it + * @param[in] name + * The environment variable name to look up. + * + * @param[in] default_path + * If the environment variable value is not found, the value to return instead. + * + * @param[in] default_path_size + * The length (including 0-terminator) of `default_path` in chars. + * + * @param[out] env_size + * Pointer to a size_t to write the length of the returned string to (optional). + * + * @return + * The allocated string containing the environment variable value or the default or "/". + */ +ENVIRONMENT_API char *environment_variable_path_create(const char *const name, const char *const default_path, const size_t default_path_size, size_t *const env_size); ENVIRONMENT_API void environment_variable_path_destroy(char *variable_path); diff --git a/source/environment/source/environment_variable_path.c b/source/environment/source/environment_variable_path.c index 53f492dc3..f36439a72 100644 --- a/source/environment/source/environment_variable_path.c +++ b/source/environment/source/environment_variable_path.c @@ -43,61 +43,32 @@ /* -- Methods -- */ -char *environment_variable_path_create(const char *name, const char *default_path, size_t default_path_size, size_t *env_size) +char *environment_variable_path_create(const char *const name, const char *const default_path, const size_t default_path_size, size_t *const env_size) { - const char *path_ptr = getenv(name); - char *path; - size_t length, size, last, end; - - if (path_ptr == NULL) - { - if (default_path == NULL) - { - static const char empty_path[] = ""; - - default_path = empty_path; - default_path_size = sizeof(empty_path); - } - - path_ptr = default_path; - length = default_path_size - 1; - } - else - { - length = strlen(path_ptr); - } - - last = length - 1; - - if (ENVIRONMENT_VARIABLE_PATH_SEPARATOR(path_ptr[last])) + const char *value = getenv(name); + size_t size; + if (value) + size = strlen(value) + 1; + else if (default_path) { - end = length; - size = length + 1; + value = default_path; + size = default_path_size; } else { - last = length; - end = length + 1; - size = length + 2; + value = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR; + size = sizeof(ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); } - - path = malloc(sizeof(char) * size); - - if (path == NULL) - { - return NULL; - } - - strncpy(path, path_ptr, length); - - path[last] = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_C; - path[end] = '\0'; - - if (env_size != NULL) - { - *env_size = size; - } - + size_t alloc_size = size; + if (size > 1) + alloc_size += !ENVIRONMENT_VARIABLE_PATH_SEPARATOR(value[size - 2]); + char *const path = malloc(sizeof(char) * alloc_size); + memcpy(path, value, sizeof(char) * size); + if (size > 1) + path[alloc_size - 2] = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_C; + path[alloc_size - 1] = '\0'; + if (env_size) + *env_size = alloc_size; return path; } diff --git a/source/portability/include/portability/portability_path.h b/source/portability/include/portability/portability_path.h index 79ff0761b..100b129f1 100644 --- a/source/portability/include/portability/portability_path.h +++ b/source/portability/include/portability/portability_path.h @@ -109,9 +109,55 @@ extern "C" { /* -- Methods -- */ -PORTABILITY_API size_t portability_path_get_name(const char *path, size_t path_size, char *name, size_t name_size); +/** + * @brief + * Get the file name portion out of a path and strip away the file extension if any. + * + * If `path` is NULL this will return an empty string. + * + * If `name` is NULL or `name_size is 0 this will return the size it requires in order to write `name`. + * + * If `path` or `name` are not NULL, then `path_size` or `name_size`, respectively, must be set to <= the length (including 0-terminator) of the memory regions pointed to by `path` and `name`. + * @param[in] path + * The full path to extract the name from. + * @param[in] path_size + * The length (including 0-terminator) of `path` in chars. + * @param[out] name + * The memory location to write the extracted name to. If `NULL` the size required will be returned instead of the size written. + * @param[in] name_size + * The size of the memory location pointed to by `name`. + * @return + * The size of the name. + */ +PORTABILITY_API size_t portability_path_get_name(const char *const path, const size_t path_size, char *const name, const size_t name_size); -PORTABILITY_API size_t portability_path_get_name_canonical(const char *path, size_t path_size, char *name, size_t name_size); +/** + * @brief + * Get the file name portion out of a path and strip away any amount of file extensions. + * + * When called with `"/foo/bar.baz.qux"`: + * + * - `portability_path_get_name` will produce the string `"bar.baz"` + * + * - `portability_path_get_name_canonical` will produce the string `"bar"` + * + * If `path` is NULL this will return an empty string. + * + * If `name` is NULL or `name_size is 0 this will return the size it requires in order to write `name`. + * + * If `path` or `name` are not NULL, then `path_size` or `name_size`, respectively, must be set to <= the length (including 0-terminator) of the memory regions pointed to by `path` and `name`. + * @param[in] path + * The full path to extract the name from. + * @param[in] path_size + * The length (including 0-terminator) of `path` in chars. + * @param[out] name + * The memory location to write the extracted name to. If `NULL` the size required will be returned instead of the size written. + * @param[in] name_size + * The size of the memory location pointed to by `name`. + * @return + * The size of the name. + */ +PORTABILITY_API size_t portability_path_get_name_canonical(const char *const path, const size_t path_size, char *const name, const size_t name_size); PORTABILITY_API size_t portability_path_get_fullname(const char *path, size_t path_size, char *name, size_t name_size); diff --git a/source/portability/source/portability_path.c b/source/portability/source/portability_path.c index 9606a7d69..096df995e 100644 --- a/source/portability/source/portability_path.c +++ b/source/portability/source/portability_path.c @@ -25,107 +25,81 @@ /* Define separator checking for any platform */ #define PORTABILITY_PATH_SEPARATOR_ALL(chr) (chr == '\\' || chr == '/') -size_t portability_path_get_name(const char *path, size_t path_size, char *name, size_t name_size) +static size_t basename_offset(const char *const path, const size_t path_size) { - size_t i, count, last; - - if (path == NULL || name == NULL) - { - return 0; - } - - for (i = 0, count = 0, last = 0; path[i] != '\0' && i < path_size && count < name_size; ++i) - { - name[count++] = path[i]; - - if (PORTABILITY_PATH_SEPARATOR(path[i])) - { - count = 0; - } - else if (path[i] == '.') - { - if (i > 0 && path[i - 1] == '.') - { - last = 0; - count = 0; - } - else - { - if (count > 0) - { - last = count - 1; - } - else - { - last = 0; - } - } - } - } + size_t offset = path_size; + for (; offset != 0; offset--) + if (PORTABILITY_PATH_SEPARATOR(path[offset - 1])) + break; + return offset; +} - if ((last == 0 && count > 1) || last > count) +size_t portability_path_get_name(const char *const path, const size_t path_size, char *const name, const size_t name_size) +{ + if (path == NULL) { - last = count; + if (name == NULL || name_size == 0) + return 0; + name[0] = '\0'; + return 1; } - - name[last] = '\0'; - - return last + 1; + // find rightmost path separator + const size_t name_start = basename_offset(path, path_size); + // Find rightmost dot + size_t rightmost_dot = path_size; + for (; rightmost_dot != name_start; rightmost_dot--) + if (path[rightmost_dot - 1] == '.') + break; + // No dots found, or name starts with dot and is non-empty, use whole name + if (rightmost_dot == name_start || (rightmost_dot == name_start + 1 && rightmost_dot != path_size - 1)) + rightmost_dot = path_size - 1; + // remove all consecutive dots at the end + while (rightmost_dot != name_start && path[rightmost_dot - 1] == '.') + rightmost_dot--; + const size_t length = rightmost_dot - name_start; + const size_t size = length + 1; + // Return required size + if (name == NULL || size > name_size) + return size; + if (length) + memcpy(name, path + name_start, length); + name[length] = '\0'; + return size; } -size_t portability_path_get_name_canonical(const char *path, size_t path_size, char *name, size_t name_size) +size_t portability_path_get_name_canonical(const char *const path, const size_t path_size, char *const name, const size_t name_size) { - if (path == NULL || name == NULL) + if (path == NULL) { - return 0; + if (name == NULL || name_size == 0) + return 0; + name[0] = '\0'; + return 1; } - - size_t i, count, last; - - for (i = 0, count = 0, last = 0; path[i] != '\0' && i < path_size && count < name_size; ++i) - { - name[count++] = path[i]; - - if (PORTABILITY_PATH_SEPARATOR(path[i])) - { - count = 0; - } - else if (path[i] == '.') - { - if (i > 0 && path[i - 1] == '.') - { - last = 0; - count = 0; - } - else - { - if (count > 0) - { - last = count - 1; - } - else - { - last = 0; - } - - /* This function is the same as portability_path_get_name but - returns the name of the file without any extension, for example: - - portability_path_get_name of libnode.so.72 is libnode.so - - portability_path_get_name_canonical of libnode.so.72 is libnode - */ + // find rightmost path separator + const size_t name_start = basename_offset(path, path_size); + // find leftmost dot + size_t leftmost_dot = name_start; + for (; leftmost_dot < path_size; leftmost_dot++) + if (path[leftmost_dot] == '.') + break; + // No dots found, use whole name + if (leftmost_dot == path_size) + leftmost_dot--; + // name starts with dot, use the following dot instead + if (leftmost_dot == name_start) + for (leftmost_dot = name_start + 1; leftmost_dot < path_size; leftmost_dot++) + if (path[leftmost_dot] == '.') break; - } - } - } - - if (last == 0 && count > 1) - { - last = count; - } - - name[last] = '\0'; - - return last + 1; + const size_t length = leftmost_dot - name_start; + const size_t size = length + 1; + // Return required size + if (name == NULL || size > name_size) + return size; + if (length) + memcpy(name, path + name_start, length); + name[length] = '\0'; + return size; } size_t portability_path_get_fullname(const char *path, size_t path_size, char *name, size_t name_size) diff --git a/source/tests/portability_path_test/source/portability_path_test.cpp b/source/tests/portability_path_test/source/portability_path_test.cpp index 15534b235..f4c638c2f 100644 --- a/source/tests/portability_path_test/source/portability_path_test.cpp +++ b/source/tests/portability_path_test/source/portability_path_test.cpp @@ -68,6 +68,33 @@ TEST_F(portability_path_test, portability_path_test_path_get_module_name_with_ra EXPECT_EQ((char)'\0', (char)result[size - 1]); } +TEST_F(portability_path_test, portability_path_test_path_get_name_null) +{ + static const char result[] = ""; + + string_name name; + + size_t size = portability_path_get_name(NULL, 0, name, NAME_SIZE); + + EXPECT_STREQ(name, result); + EXPECT_EQ((size_t)size, (size_t)sizeof(result)); + EXPECT_EQ((char)'\0', (char)result[size - 1]); +} + +TEST_F(portability_path_test, portability_path_test_path_get_name_empty) +{ + static const char base[] = ""; + static const char result[] = ""; + + string_name name; + + size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); + + EXPECT_STREQ(name, result); + EXPECT_EQ((size_t)size, (size_t)sizeof(result)); + EXPECT_EQ((char)'\0', (char)result[size - 1]); +} + TEST_F(portability_path_test, portability_path_test_path_get_name) { static const char base[] = "/a/b/c/asd.txt"; @@ -110,6 +137,34 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_without_dot) EXPECT_EQ((char)'\0', (char)result[size - 1]); } +TEST_F(portability_path_test, portability_path_test_path_get_name_dot_in_path) +{ + static const char base[] = "/a/b.c/d/asd"; + static const char result[] = "asd"; + + string_name name; + + size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); + + EXPECT_STREQ(name, result); + EXPECT_EQ((size_t)size, (size_t)sizeof(result)); + EXPECT_EQ((char)'\0', (char)result[size - 1]); +} + +TEST_F(portability_path_test, portability_path_test_path_get_name_dot_in_path_and_name) +{ + static const char base[] = "/a/b.c/d/asd.txt"; + static const char result[] = "asd"; + + string_name name; + + size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); + + EXPECT_STREQ(name, result); + EXPECT_EQ((size_t)size, (size_t)sizeof(result)); + EXPECT_EQ((char)'\0', (char)result[size - 1]); +} + TEST_F(portability_path_test, portability_path_test_path_get_name_only_separator_dot) { static const char base[] = "/."; From 282887dcdc6e585398318c5761b69159ee10535e Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Sat, 4 Oct 2025 11:26:54 +0200 Subject: [PATCH 107/109] Review of Thomas PR. --- .../environment/environment_variable_path.h | 12 +- .../source/environment_variable_path.c | 43 ++++-- .../include/portability/portability_path.h | 37 +++--- source/portability/source/portability_path.c | 125 +++++++++++++----- 4 files changed, 148 insertions(+), 69 deletions(-) diff --git a/source/environment/include/environment/environment_variable_path.h b/source/environment/include/environment/environment_variable_path.h index 58b8c2047..5f3a17ba4 100644 --- a/source/environment/include/environment/environment_variable_path.h +++ b/source/environment/include/environment/environment_variable_path.h @@ -54,13 +54,11 @@ extern "C" { /** * @brief - * If the value of `name` exists as an environment variable, return a live string of its value, otherwise return a live value of `default_path` or "/". + * If the value of @name exists as an environment variable, return a live string of its value, otherwise return a live value of @default_path or "/". + * @name should not be NULL. + * If @default_path is not NULL, @default_path_size must be set to <= the length (including null-terminator) of the @default_path string. + * If @env_size is not NULL, the length (including null-terminator) of the returned string will be set to it. * - * `name` should not be `NULL`. - * - * If `default_path` is not `NULL`, `default_path_size` must be set to <= the length (including 0-terminator) of the `default_path` string. - * - * If `env_size` is not `NULL`, the length (including 0-terminator) of the returned string will be set to it * @param[in] name * The environment variable name to look up. * @@ -68,7 +66,7 @@ extern "C" { * If the environment variable value is not found, the value to return instead. * * @param[in] default_path_size - * The length (including 0-terminator) of `default_path` in chars. + * The length (including null-terminator) of @default_path in chars. * * @param[out] env_size * Pointer to a size_t to write the length of the returned string to (optional). diff --git a/source/environment/source/environment_variable_path.c b/source/environment/source/environment_variable_path.c index f36439a72..813112a80 100644 --- a/source/environment/source/environment_variable_path.c +++ b/source/environment/source/environment_variable_path.c @@ -45,30 +45,53 @@ char *environment_variable_path_create(const char *const name, const char *const default_path, const size_t default_path_size, size_t *const env_size) { - const char *value = getenv(name); - size_t size; - if (value) - size = strlen(value) + 1; + const char *env_variable = getenv(name); + char *path; + size_t size, alloc_size; + + if (env_variable) + { + size = strlen(env_variable) + 1; + } else if (default_path) { - value = default_path; + env_variable = default_path; size = default_path_size; } else { - value = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR; + env_variable = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR; size = sizeof(ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); } - size_t alloc_size = size; + + alloc_size = size; + if (size > 1) - alloc_size += !ENVIRONMENT_VARIABLE_PATH_SEPARATOR(value[size - 2]); - char *const path = malloc(sizeof(char) * alloc_size); - memcpy(path, value, sizeof(char) * size); + { + alloc_size += !ENVIRONMENT_VARIABLE_PATH_SEPARATOR(env_variable[size - 2]); + } + + path = malloc(sizeof(char) * alloc_size); + + if (path == NULL) + { + return NULL; + } + + memcpy(path, env_variable, sizeof(char) * size); + if (size > 1) + { path[alloc_size - 2] = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_C; + } + path[alloc_size - 1] = '\0'; + if (env_size) + { *env_size = alloc_size; + } + return path; } diff --git a/source/portability/include/portability/portability_path.h b/source/portability/include/portability/portability_path.h index 100b129f1..38e743fbf 100644 --- a/source/portability/include/portability/portability_path.h +++ b/source/portability/include/portability/portability_path.h @@ -112,20 +112,22 @@ extern "C" { /** * @brief * Get the file name portion out of a path and strip away the file extension if any. + * If @path is NULL this will return an empty string. + * If @name is NULL or @name_size is 0 this will return the size it requires in order to write @name. + * If @path or @name are not NULL, then @path_size or @name_size, respectively, must be set to <= the length (including null-terminator) of the memory regions pointed to by @path and @name. * - * If `path` is NULL this will return an empty string. - * - * If `name` is NULL or `name_size is 0 this will return the size it requires in order to write `name`. - * - * If `path` or `name` are not NULL, then `path_size` or `name_size`, respectively, must be set to <= the length (including 0-terminator) of the memory regions pointed to by `path` and `name`. * @param[in] path * The full path to extract the name from. + * * @param[in] path_size - * The length (including 0-terminator) of `path` in chars. + * The length (including null-terminator) of @path in chars. + * * @param[out] name - * The memory location to write the extracted name to. If `NULL` the size required will be returned instead of the size written. + * The memory location to write the extracted name to. If NULL the size required will be returned instead of the size written. + * * @param[in] name_size - * The size of the memory location pointed to by `name`. + * The size of the memory location pointed to by @name. + * * @return * The size of the name. */ @@ -134,26 +136,27 @@ PORTABILITY_API size_t portability_path_get_name(const char *const path, const s /** * @brief * Get the file name portion out of a path and strip away any amount of file extensions. - * * When called with `"/foo/bar.baz.qux"`: * * - `portability_path_get_name` will produce the string `"bar.baz"` - * * - `portability_path_get_name_canonical` will produce the string `"bar"` * - * If `path` is NULL this will return an empty string. - * - * If `name` is NULL or `name_size is 0 this will return the size it requires in order to write `name`. + * If @path is NULL this will return an empty string. + * If @name is NULL or @name_size is 0 this will return the size it requires in order to write @name. + * If @path or @name are not NULL, then @path_size or @name_size, respectively, must be set to <= the length (including null-terminator) of the memory regions pointed to by @path and @name. * - * If `path` or `name` are not NULL, then `path_size` or `name_size`, respectively, must be set to <= the length (including 0-terminator) of the memory regions pointed to by `path` and `name`. * @param[in] path * The full path to extract the name from. + * * @param[in] path_size - * The length (including 0-terminator) of `path` in chars. + * The length (including null-terminator) of @path in chars. + * * @param[out] name - * The memory location to write the extracted name to. If `NULL` the size required will be returned instead of the size written. + * The memory location to write the extracted name to. If NULL the size required will be returned instead of the size written. + * * @param[in] name_size - * The size of the memory location pointed to by `name`. + * The size of the memory location pointed to by @name. + * * @return * The size of the name. */ diff --git a/source/portability/source/portability_path.c b/source/portability/source/portability_path.c index 096df995e..207a9cf29 100644 --- a/source/portability/source/portability_path.c +++ b/source/portability/source/portability_path.c @@ -25,80 +25,135 @@ /* Define separator checking for any platform */ #define PORTABILITY_PATH_SEPARATOR_ALL(chr) (chr == '\\' || chr == '/') -static size_t basename_offset(const char *const path, const size_t path_size) +static size_t portability_path_basename_offset(const char *const path, const size_t path_size) { size_t offset = path_size; - for (; offset != 0; offset--) - if (PORTABILITY_PATH_SEPARATOR(path[offset - 1])) - break; + + while (offset > 0 && !PORTABILITY_PATH_SEPARATOR(path[offset - 1])) + { + --offset; + } + return offset; } size_t portability_path_get_name(const char *const path, const size_t path_size, char *const name, const size_t name_size) { + size_t name_start, rightmost_dot, length, size; + if (path == NULL) { if (name == NULL || name_size == 0) + { return 0; + } + name[0] = '\0'; + return 1; } - // find rightmost path separator - const size_t name_start = basename_offset(path, path_size); - // Find rightmost dot - size_t rightmost_dot = path_size; - for (; rightmost_dot != name_start; rightmost_dot--) - if (path[rightmost_dot - 1] == '.') - break; - // No dots found, or name starts with dot and is non-empty, use whole name + + /* Find rightmost path separator */ + name_start = portability_path_basename_offset(path, path_size); + + /* Find rightmost dot */ + rightmost_dot = path_size; + + while (rightmost_dot != name_start && path[rightmost_dot - 1] != '.') + { + --rightmost_dot; + } + + /* No dots found, or name starts with dot and is non-empty, use whole name */ if (rightmost_dot == name_start || (rightmost_dot == name_start + 1 && rightmost_dot != path_size - 1)) + { rightmost_dot = path_size - 1; - // remove all consecutive dots at the end + } + + /* Remove all consecutive dots at the end */ while (rightmost_dot != name_start && path[rightmost_dot - 1] == '.') - rightmost_dot--; - const size_t length = rightmost_dot - name_start; - const size_t size = length + 1; - // Return required size + { + --rightmost_dot; + } + + length = rightmost_dot - name_start; + size = length + 1; + + /* Return required size */ if (name == NULL || size > name_size) + { return size; - if (length) + } + + if (length > 0) + { memcpy(name, path + name_start, length); + } + name[length] = '\0'; + return size; } size_t portability_path_get_name_canonical(const char *const path, const size_t path_size, char *const name, const size_t name_size) { + size_t name_start, leftmost_dot, length, size; + if (path == NULL) { if (name == NULL || name_size == 0) + { return 0; + } + name[0] = '\0'; + return 1; } - // find rightmost path separator - const size_t name_start = basename_offset(path, path_size); - // find leftmost dot - size_t leftmost_dot = name_start; - for (; leftmost_dot < path_size; leftmost_dot++) - if (path[leftmost_dot] == '.') - break; - // No dots found, use whole name + + /* Find rightmost path separator */ + name_start = portability_path_basename_offset(path, path_size); + + /* Find leftmost dot */ + leftmost_dot = name_start; + + while (leftmost_dot < path_size && path[leftmost_dot] != '.') + { + ++leftmost_dot; + } + + /* No dots found, use whole name */ if (leftmost_dot == path_size) - leftmost_dot--; - // name starts with dot, use the following dot instead + { + --leftmost_dot; + } + + /* Name starts with dot, use the following dot instead */ if (leftmost_dot == name_start) - for (leftmost_dot = name_start + 1; leftmost_dot < path_size; leftmost_dot++) - if (path[leftmost_dot] == '.') - break; - const size_t length = leftmost_dot - name_start; - const size_t size = length + 1; - // Return required size + { + do + { + ++leftmost_dot; + + } while (leftmost_dot < path_size && path[leftmost_dot] != '.'); + } + + length = leftmost_dot - name_start; + size = length + 1; + + /* Return required size */ if (name == NULL || size > name_size) + { return size; - if (length) + } + + if (length > 0) + { memcpy(name, path + name_start, length); + } + name[length] = '\0'; + return size; } From 77e9ddb2312950dbf0fa5b291883a799eeb94326 Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Sat, 4 Oct 2025 17:48:55 +0200 Subject: [PATCH 108/109] Improve cxx port. --- source/ports/cxx_port/CMakeLists.txt | 33 ++--- .../cxx_port/include/metacall/metacall.hpp | 127 +++++++++++++++++- .../cxx_port/inline/metacall/metacall.inl | 40 ------ .../source/metacall_cxx_port_test.cpp | 81 +++++++++++ 4 files changed, 211 insertions(+), 70 deletions(-) delete mode 100644 source/ports/cxx_port/inline/metacall/metacall.inl diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index e3e79398a..c681dacd1 100644 --- a/source/ports/cxx_port/CMakeLists.txt +++ b/source/ports/cxx_port/CMakeLists.txt @@ -34,14 +34,9 @@ include(SecurityFlags) # Sources # -set(inline_path "${CMAKE_CURRENT_SOURCE_DIR}/inline/metacall") set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/metacall") set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") -set(inlines - ${inline_path}/metacall.inl -) - set(headers ${include_path}/metacall.hpp ) @@ -51,11 +46,8 @@ set(sources ) # Group source files -set(inline_group "Inline Files") set(header_group "Header Files (API)") set(source_group "Source Files") -source_group_by_path(${inline_path} "\\\\.inl$" - ${inline_group} ${inlines}) source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" ${header_group} ${headers}) source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" @@ -67,7 +59,6 @@ source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" # Build library add_library(${target} - ${inlines} ${sources} ${headers} ) @@ -104,10 +95,6 @@ target_include_directories(${target} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include - ${PROJECT_BINARY_DIR}/source/inline - ${CMAKE_CURRENT_SOURCE_DIR}/inline - ${CMAKE_CURRENT_BINARY_DIR}/inline - PUBLIC ${DEFAULT_INCLUDE_DIRECTORIES} @@ -115,11 +102,6 @@ target_include_directories(${target} $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> - - - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inline> - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/inline> - $<INSTALL_INTERFACE:inline> ) # @@ -165,6 +147,15 @@ target_compile_options(${target} INTERFACE ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # @@ -187,9 +178,3 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/metacall DESTINATION ${INSTALL_INCLUDE} COMPONENT dev ) - -# Inline files -install(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/inline/metacall DESTINATION ${INSTALL_INCLUDE} - COMPONENT dev -) diff --git a/source/ports/cxx_port/include/metacall/metacall.hpp b/source/ports/cxx_port/include/metacall/metacall.hpp index d92a81638..443e9dbd9 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -86,7 +86,6 @@ class METACALL_API value : public value_base throw std::runtime_error("Unsupported MetaCall value"); } -private: // Type-specific creation (calls specialized version below) static void *create(const T &v); @@ -338,6 +337,123 @@ inline std::nullptr_t value<std::nullptr_t>::to_value() const // TODO: Future, Function, Class, Object, Exception, Throwable... +class METACALL_API value_ref +{ +public: + explicit value_ref(void *ptr) : + ptr(ptr) {} + + template <typename T> + T as() const + { + return value<T>(ptr).to_value(); + } + +private: + void *ptr; +}; + +class METACALL_API array : public value_base +{ +public: + template <typename... Args> + explicit array(Args &&...args) : + value_base(create(std::forward<Args>(args)...), &metacall_value_destroy) + { + if (value_ptr == nullptr) + { + throw std::runtime_error("Failed to create MetaCall array"); + } + } + + explicit array(void *array_value) : + value_base(array_value, &value_base::noop_destructor) {} + + void **to_value() const + { + void **array_ptr = metacall_value_to_array(value_ptr.get()); + + if (array_ptr == NULL) + { + throw std::runtime_error("Invalid MetaCall array"); + } + + return array_ptr; + } + + template <typename T> + T get(std::size_t index) const + { + void **array_ptr = to_value(); + + return value<T>(array_ptr[index]).to_value(); + } + + value_ref operator[](std::size_t index) const + { + void **array_ptr = to_value(); + + return value_ref(array_ptr[index]); + } + + static enum metacall_value_id id() + { + return METACALL_ARRAY; + } + +private: + // Recursive function to create and fill the MetaCall array + template <typename... Args> + static void *create(Args &&...args) + { + constexpr std::size_t size = sizeof...(Args); + + // Create the array with null data initially + void *array_value = metacall_value_create_array(NULL, size); + + if (array_value == NULL) + { + throw std::runtime_error("Failed to create MetaCall value array"); + } + + // Get the internal C array + void **array_ptr = metacall_value_to_array(array_value); + + // Helper to unpack the args into array + create_array(array_ptr, 0, std::forward<Args>(args)...); + + return array_value; + } + + // Recursive unpacking using fold expression (C++17+) + template <typename... Args> + static void create_array(void **array_ptr, std::size_t index, Args &&...args) + { + // Use initializer list trick to expand the pack + (( + array_ptr[index++] = value<std::decay_t<Args>>::create(std::forward<Args>(args))), + ...); + } +}; + +template <> +inline void *value<array>::create(const array &v) +{ + return metacall_value_copy(v.to_raw()); +} + +template <> +inline enum metacall_value_id value<array>::id() +{ + return METACALL_ARRAY; +} + +template <> +inline array value<array>::to_value() const +{ + return array(to_raw()); +} + template <typename K, typename V> class METACALL_API map : public value_base { @@ -422,12 +538,11 @@ class METACALL_API map : public value_base }; template <typename... Ts> -METACALL_API int metacall(std::string name, Ts... ts); +METACALL_API int metacall(std::string name, Ts... ts) +{ + return 0; +} } /* namespace metacall */ -// TODO: Move everything to metacall.inl - -#include <metacall/metacall.inl> - #endif /* METACALL_HPP */ diff --git a/source/ports/cxx_port/inline/metacall/metacall.inl b/source/ports/cxx_port/inline/metacall/metacall.inl deleted file mode 100644 index 8223b5be0..000000000 --- a/source/ports/cxx_port/inline/metacall/metacall.inl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Format Library by Parra Studios - * A cross-platform library for supporting formatted input / output. - * - * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef METACALL_INL -#define METACALL_INL 1 - -/* -- Headers -- */ - -#include <metacall/metacall_api.h> - -#include <string> - -namespace metacall -{ -template <typename... Ts> -METACALL_API int metacall(std::string name, Ts... ts) -{ - return 0; -} - -} /* namespace metacall */ - -#endif /* METACALL_INL */ diff --git a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp index 6865b258f..516e1f27b 100644 --- a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -46,6 +46,48 @@ void *cxx_map_test(size_t argc, void *args[], void *data) return metacall_value_create_null(); } +void *cxx_array_test(size_t argc, void *args[], void *data) +{ + array a(args[0]); + + (void)argc; + (void)data; + + EXPECT_EQ((float)a[0].as<int>(), (int)3); + EXPECT_EQ((float)a[1].as<float>(), (float)4.0f); + + EXPECT_EQ((float)a.get<int>(0), (int)3); + EXPECT_EQ((float)a.get<float>(1), (float)4.0f); + + printf("a[0] => %d\n", a[0].as<int>()); + printf("a[1] => %f\n", a[1].as<float>()); + fflush(stdout); + + return metacall_value_create_null(); +} + +void *cxx_map_array_test(size_t argc, void *args[], void *data) +{ + map<std::string, array> m(args[0]); + + (void)argc; + (void)data; + + EXPECT_STREQ(m["includes"][0].as<std::string>().c_str(), "/a/path"); + EXPECT_STREQ(m["includes"][1].as<std::string>().c_str(), "/another/path"); + + EXPECT_STREQ(m["libraries"][0].as<std::string>().c_str(), "/a/path"); + EXPECT_STREQ(m["libraries"][1].as<std::string>().c_str(), "/another/path"); + + printf("m['includes'][0] => %s\n", m["includes"][0].as<std::string>().c_str()); + printf("m['includes'][1] => %s\n", m["includes"][1].as<std::string>().c_str()); + + printf("m['libraries'][0] => %s\n", m["libraries"][0].as<std::string>().c_str()); + printf("m['libraries'][1] => %s\n", m["libraries"][1].as<std::string>().c_str()); + + return metacall_value_create_null(); +} + // TODO: /* void *cxx_recursive_map_test(size_t argc, void *args[], void *data) @@ -89,6 +131,45 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) metacall_value_destroy(ret); } + { + array a(3, 4.0f); + + void *args[] = { + a.to_raw() + }; + + metacall_register("cxx_array_test", cxx_array_test, NULL, METACALL_NULL, 1, METACALL_ARRAY); + + void *ret = metacallv_s("cxx_array_test", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + } + + { + map<std::string, array> m = { + { "includes", array("/a/path", "/another/path") }, + { "libraries", array("/a/path", "/another/path") } + }; + + void *args[] = { + m.to_raw() + }; + + metacall_register("cxx_map_array_test", cxx_map_array_test, NULL, METACALL_NULL, 1, METACALL_MAP); + + void *ret = metacallv_s("cxx_map_array_test", args, 1); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + + metacall_value_destroy(ret); + } + // TODO: /* { From 057d988c43d798eb9c5494d2f372a279f4c2df9c Mon Sep 17 00:00:00 2001 From: Vicente Eduardo Ferrer Garcia <vic798@gmail.com> Date: Thu, 9 Oct 2025 17:12:41 +0200 Subject: [PATCH 109/109] Improve metacall cxx port. --- source/ports/cxx_port/CMakeLists.txt | 8 +++ .../cxx_port/include/metacall/metacall.hpp | 51 ++++++++++++-- .../cxx_port/include/metacall/metacall.inl | 31 +++++++++ .../source/metacall_cxx_port_test.cpp | 66 +++++++------------ 4 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 source/ports/cxx_port/include/metacall/metacall.inl diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index c681dacd1..13657ce94 100644 --- a/source/ports/cxx_port/CMakeLists.txt +++ b/source/ports/cxx_port/CMakeLists.txt @@ -41,15 +41,22 @@ set(headers ${include_path}/metacall.hpp ) +set(inline + ${include_path}/metacall.inl +) + set(sources ${source_path}/metacall.cpp ) # Group source files set(header_group "Header Files (API)") +set(inline_group "Inline Files") set(source_group "Source Files") source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" ${header_group} ${headers}) +source_group_by_path(${include_path} "\\\\.inl$" + ${inline_group} ${inlines}) source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" ${source_group} ${sources}) @@ -61,6 +68,7 @@ source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" add_library(${target} ${sources} ${headers} + ${inline} ) # Create namespaced alias diff --git a/source/ports/cxx_port/include/metacall/metacall.hpp b/source/ports/cxx_port/include/metacall/metacall.hpp index 443e9dbd9..9092bbfe9 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -72,8 +72,8 @@ class METACALL_API value : public value_base } } - explicit value(void *value_ptr) : - value_base(value_ptr, &value_base::noop_destructor) + explicit value(void *value_ptr, void (*destructor)(void *) = &value_base::noop_destructor) : + value_base(value_ptr, destructor) { if (metacall_value_id(value_ptr) != id()) { @@ -537,12 +537,53 @@ class METACALL_API map : public value_base std::unordered_map<K, pair_value_type> m; }; -template <typename... Ts> -METACALL_API int metacall(std::string name, Ts... ts) +namespace detail +{ +template <typename T> +constexpr bool is_value_base = std::is_base_of_v<value_base, std::remove_cv_t<std::remove_reference_t<T>>>; + +template <typename T> +value_base to_value_base(T &&arg) { - return 0; + if constexpr (is_value_base<T>) + { + return std::move(arg); + } + else + { + return value<std::decay_t<T>>(std::forward<T>(arg)); + } +} + +} /* namespace detail */ + +template <typename Ret, typename... Args> +METACALL_API Ret metacall(std::string name, Args &&...args) +{ + constexpr std::size_t size = sizeof...(Args); + std::array<value_base, size> value_args = { { detail::to_value_base(std::forward<Args>(args))... } }; + void *raw_args[size]; + + for (std::size_t i = 0; i < size; ++i) + { + raw_args[i] = value_args[i].to_raw(); + } + + void *ret = metacallv_s(name.c_str(), raw_args, size); + + if (ret == NULL) + { + throw std::runtime_error("MetaCall invokation to '" + name + "' has failed by returning NULL"); + } + + value<Ret> result(ret, &metacall_value_destroy); + + return result.to_value(); } } /* namespace metacall */ +// TODO: Move implementations to metacall.inl +#include <metacall/metacall.inl> + #endif /* METACALL_HPP */ diff --git a/source/ports/cxx_port/include/metacall/metacall.inl b/source/ports/cxx_port/include/metacall/metacall.inl new file mode 100644 index 000000000..81a48f839 --- /dev/null +++ b/source/ports/cxx_port/include/metacall/metacall.inl @@ -0,0 +1,31 @@ +/* + * Format Library by Parra Studios + * A cross-platform library for supporting formatted input / output. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef METACALL_INL +#define METACALL_INL 1 + +/* -- Headers -- */ + +namespace metacall +{ + +} /* namespace metacall */ + +#endif /* METACALL_INL */ diff --git a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp index 516e1f27b..23998054e 100644 --- a/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -106,6 +106,20 @@ void *cxx_recursive_map_test(size_t argc, void *args[], void *data) } */ +void *cxx_float_int_int_test(size_t argc, void *args[], void *data) +{ + value<int> a0(args[0]); + value<int> a1(args[1]); + + (void)argc; + (void)data; + + EXPECT_EQ(a0.to_value(), 7); + EXPECT_EQ(a1.to_value(), 8); + + return metacall_value_create_float(3.0f); +} + TEST_F(metacall_cxx_port_test, DefaultConstructor) { ASSERT_EQ((int)0, (int)metacall_initialize()); @@ -116,37 +130,17 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) { "world", 4.0f } }; - void *args[] = { - m.to_raw() - }; - metacall_register("cxx_map_test", cxx_map_test, NULL, METACALL_NULL, 1, METACALL_MAP); - void *ret = metacallv_s("cxx_map_test", args, 1); - - EXPECT_NE((void *)NULL, (void *)ret); - - EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); - - metacall_value_destroy(ret); + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_map_test", m)); } { array a(3, 4.0f); - void *args[] = { - a.to_raw() - }; - metacall_register("cxx_array_test", cxx_array_test, NULL, METACALL_NULL, 1, METACALL_ARRAY); - void *ret = metacallv_s("cxx_array_test", args, 1); - - EXPECT_NE((void *)NULL, (void *)ret); - - EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); - - metacall_value_destroy(ret); + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_array_test", a)); } { @@ -155,19 +149,9 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) { "libraries", array("/a/path", "/another/path") } }; - void *args[] = { - m.to_raw() - }; - metacall_register("cxx_map_array_test", cxx_map_array_test, NULL, METACALL_NULL, 1, METACALL_MAP); - void *ret = metacallv_s("cxx_map_array_test", args, 1); - - EXPECT_NE((void *)NULL, (void *)ret); - - EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); - - metacall_value_destroy(ret); + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_map_array_test", m)); } // TODO: @@ -177,21 +161,17 @@ TEST_F(metacall_cxx_port_test, DefaultConstructor) { "hello", { "world", 4.0f } } }; - void *args[] = { - m.to_raw() - }; - metacall_register("cxx_recursive_map_test", cxx_recursive_map_test, NULL, METACALL_NULL, 1, METACALL_MAP); - void *ret = metacallv_s("cxx_recursive_map_test", args, 1); - - EXPECT_NE((void *)NULL, (void *)ret); + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_recursive_map_test", m)); + } + */ - EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_NULL); + { + metacall_register("cxx_float_int_int_test", cxx_float_int_int_test, NULL, METACALL_FLOAT, 2, METACALL_INT, METACALL_INT); - metacall_value_destroy(ret); + EXPECT_EQ(3.0f, metacall::metacall<float>("cxx_float_int_int_test", 7, 8)); } - */ /* Print inspect information */ {