diff --git a/.env b/.env index 2e5bae29aa..cf3ae699c0 100644 --- a/.env +++ b/.env @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 33349ce4d7..67a684cd07 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 @@ -56,12 +88,10 @@ jobs: - name: Build working-directory: ./build - # TODO: Remove the disable option for fork safe once funchook problem is solved run: | if [ "$(uname)" == "Darwin" ]; then . .env fi - cmake -DOPTION_FORK_SAFE=OFF .. bash ../tools/metacall-build.sh $METACALL_BUILD_OPTIONS env: METACALL_BUILD_OPTIONS: release benchmarks @@ -101,7 +131,7 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-2019] + os: [windows-2022, windows-2025] env: LTTNG_UST_REGISTER_TIMEOUT: 0 diff --git a/.github/workflows/docker-hub-platform.yml b/.github/workflows/docker-hub-platform.yml deleted file mode 100644 index 32f9fe5d2f..0000000000 --- a/.github/workflows/docker-hub-platform.yml +++ /dev/null @@ -1,164 +0,0 @@ -name: Build and Push Docker Image for Multiple Architectures - -on: - pull_request: - push: - branches: - - master - - develop - tags: - - 'v*.*.*' - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -env: - IMAGE_NAME: index.docker.io/metacall/core - BUILDKIT_VERSION: 0.13.0 - -jobs: - build: - name: Build - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - platform: - - linux/amd64 - - linux/arm64 - - linux/riscv64 - - linux/ppc64le - - linux/s390x - - linux/386 - - linux/arm/v7 - - linux/arm/v6 - # - linux/mips64le - # - linux/mips64 - - steps: - - name: Checkout the code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_NAME }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Docker Setup BuildX - uses: docker/setup-buildx-action@v3 - with: - version: v${{ env.BUILDKIT_VERSION }} - - - name: Verify Docker BuildX Version - run: docker buildx version - - - name: Authenticate to Docker registry - if: github.event_name != 'pull_request' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Build MetaCall Docker Images - env: - METACALL_PLATFORM: ${{ matrix.platform }} - run: | - ./docker-compose.sh platform - - # - name: Generate images - # if: github.event_name != 'pull_request' - # run: | - # for tag in "deps" "dev" "runtime" "cli"; do - # mkdir -p "/tmp/images/${tag}" - # digest="$(docker images --no-trunc --quiet metacall/core:${tag})" - # echo "FROM metacall/core:${tag}@${digest}" &> "/tmp/images/${tag}/Dockerfile" - # done - - # - name: Build and push by digest (deps) - # id: build - # uses: docker/build-push-action@v6 - # if: github.event_name != 'pull_request' - # with: - # context: /tmp/images/deps/Dockerfile - # platforms: ${{ matrix.platform }} - # labels: ${{ steps.meta.outputs.labels }} - # outputs: type=image,name=docker.io/${{ env.IMAGE_NAME }}:deps,push-by-digest=true,name-canonical=true,push=true - - - name: Export digests - if: github.event_name != 'pull_request' - run: | - PLATFORM=${{ matrix.platform }} - echo "PLATFORM=${PLATFORM//\//-}" >> $GITHUB_ENV - for tag in "deps" "dev" "runtime" "cli"; do - mkdir -p "/tmp/digests/${tag}" - digest="$(docker images --no-trunc --quiet metacall/core:${tag})" - touch "/tmp/digests/${tag}/${digest#sha256:}" - done - - - name: Upload digests - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v4 - with: - name: digests-${{ env.PLATFORM }} - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 - - merge: - name: Merge digests for the manifest - runs-on: ubuntu-latest - if: github.event_name != 'pull_request' - needs: - - build - steps: - - name: Download digests - uses: actions/download-artifact@v4 - with: - path: /tmp/digests - pattern: digests-* - merge-multiple: true - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - version: v${{ env.BUILDKIT_VERSION }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_NAME }} - - - name: Authenticate to Docker registry - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Create manifest list and push - if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/tags/') - run: | - for tag in "deps" "dev" "runtime" "cli"; do - cd "/tmp/digests/${tag}" - IMAGE_HASHES=$(printf '${{ env.IMAGE_NAME }}:${tag}@sha256:%s ' *) - for image in ${IMAGE_HASHES}; do - docker image tag ${image} ${{ env.IMAGE_NAME }}:${tag} - docker push ${{ env.IMAGE_NAME }}:${tag} - done - docker buildx imagetools create -t ${{ env.IMAGE_NAME }}:${tag} ${IMAGE_HASHES} - if [[ "${tag}" = "cli" ]]; then - docker buildx imagetools create -t ${{ env.IMAGE_NAME }}:latest ${IMAGE_HASHES} - if [[ "${{ contains(github.ref, 'refs/tags/') }}" = true ]]; then - TAG=${GITHUB_REF#refs/*/} - VERSION=${TAG#v} - docker buildx imagetools create -t ${{ env.IMAGE_NAME }}:${VERSION} ${IMAGE_HASHES} - fi - fi - done diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index 12375d985f..34267338aa 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -1,13 +1,11 @@ -name: Build and Push Docker Image +name: Build and Push Docker Image for Multiple Architectures on: - # To enable manual triggering of this workflow - workflow_dispatch: - - # Trigger for pushes to master and tags + pull_request: push: branches: - master + - develop tags: - 'v*.*.*' @@ -16,38 +14,201 @@ concurrency: cancel-in-progress: true env: - IMAGE_NAME: index.docker.io/metacall/core + DOCKER_REGISTRY: index.docker.io + DOCKER_USERNAME: metacall + IMAGE_NAME: core + BUILDKIT_VERSION: 0.13.0 + + # TODO: Tests failing + # - linux/s390x + # TODO: Detour not supported, needs to patch GOT instead of PLT + # - linux/mips64le + # - linux/mips64 + PLATFORM_LIST: > + [ + "linux/amd64", + "linux/amd64/v2", + "linux/amd64/v3", + "linux/386", + "linux/arm64", + "linux/riscv64", + "linux/ppc64le", + "linux/arm/v7", + "linux/arm/v6", + "linux/loong64" + ] jobs: - build: + matrix: + name: Generate Platform List runs-on: ubuntu-latest + outputs: + platform_list: ${{ steps.generate_platform_list.outputs.platform_list }} + steps: + - name: Generate platform list + id: generate_platform_list + run: | + set -exuo pipefail + PLATFORM_STRING=$(cat <> $GITHUB_ENV + echo "::set-output name=platform_list::$PLATFORM_LIST" + + build: name: Build + runs-on: ubuntu-latest + needs: matrix + strategy: + fail-fast: false + matrix: + platform: ${{ fromJSON(needs.matrix.outputs.platform_list) }} + steps: - - name: Checkout the code + - name: Checkout Repository uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Login to DockerHub - run: docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" -p "${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 - - name: Pull MetaCall Docker Images - run: bash ./docker-compose.sh pull + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v3 + with: + 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 }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Build MetaCall Docker Images - run: bash ./docker-compose.sh build + env: + METACALL_PLATFORM: ${{ matrix.platform }} + DOCKER_BUILDKIT: 1 + run: | + ./docker-compose.sh platform + + - name: Run Tests + env: + DOCKER_BUILDKIT: 1 + run: | + set -exuo pipefail + docker image inspect ${DOCKER_USERNAME}/${IMAGE_NAME}:cli --format='{{.Os}}/{{.Architecture}}' + cat < Dockerfile.test + FROM ${DOCKER_USERNAME}/${IMAGE_NAME}:cli + RUN apt-get update && apt-get install -y file + RUN file /usr/local/bin/metacallcli && ldd /usr/local/bin/metacallcli + RUN echo "console.log('0123456789abcdef')" > script.js + RUN metacallcli script.js | tee output.txt + RUN grep 0123456789abcdef output.txt + EOF + + docker buildx build --progress=plain --platform ${{ matrix.platform }} -f Dockerfile.test -t test-image . + + - name: Tag & Push Platform Images + # 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' + run: | + platform_tag=$(echo "${{ matrix.platform }}" | tr '/' '-') + for tag in "deps" "dev" "runtime" "cli"; do + docker tag \ + ${DOCKER_USERNAME}/${IMAGE_NAME}:${tag} \ + ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag} + + echo "Pushing image for tag: ${tag} with platform: ${platform_tag}" + docker push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag} + done - # TODO: Build with alpine and provide multiple tags (debian & alpine) once all tests pass - - name: Push MetaCall Docker Image to DockerHub + manifest: + name: Create and Push Manifest Lists + needs: [matrix, build] + # 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' + runs-on: ubuntu-latest + steps: + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Create and Push Manifest Lists run: | - if [[ "${{ github.ref == 'refs/heads/master' }}" = true ]]; then - bash ./docker-compose.sh push - elif [[ "${{ contains(github.ref, 'refs/tags/') }}" = true ]]; then - bash ./docker-compose.sh version - else - echo "Failed to push the docker images" - exit 1 + set -exuo pipefail + + tags=("deps" "dev" "runtime" "cli") + platforms=($(echo '${{ needs.matrix.outputs.platform_list }}' | jq -r '.[]')) + + echo "Create all the tags by platform" + + for tag in "${tags[@]}"; do + echo "Creating manifest for tag: $tag" + platform_tags="" + for platform in "${platforms[@]}"; do + platform_tag=$(echo "${platform}" | tr '/' '-') + platform_tags="${platform_tags} ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}" + done + echo "Creating manifest with tags: ${platform_tags}" + docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag} ${platform_tags} --amend + docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag} + done + + echo "Create the latest tag" + + cli_platform_tags="" + for platform in ${platforms[@]}"; do + platform_tag=$(echo "${platform}" | tr '/' '-') + cli_platform_tags="${cli_platform_tags} ${DOCKER_USERNAME}/${IMAGE_NAME}:cli-${platform_tag}" + done + docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:latest ${cli_platform_tags} --amend + docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:latest + + if [[ "${{ startsWith(github.ref, 'refs/tags/') }}" = true ]]; then + VERSION=${GITHUB_REF#refs/tags/v} + + echo "Create the version ${VERSION} tag" + + for tag in "${tags[@]}"; do + platform_tags="" + for platform in "${platforms[@]}"; do + platform_tag=$(echo "${platform}" | tr '/' '-') + platform_tags="${platform_tags} ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}" + done + docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${VERSION}-${tag} ${platform_tags} --amend + docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${VERSION}-${tag} + done fi - - name: Logout from DockerHub - run: docker logout + cleanup: + name: Cleanup Platform Specific Tags + needs: [matrix, build, manifest] + runs-on: ubuntu-latest + if: always() + steps: + - name: Remove Platform-Specific Tags + run: | + set -exuo pipefail + + tags=("deps" "dev" "runtime" "cli") + platforms=($(echo '${{ needs.matrix.outputs.platform_list }}' | jq -r '.[]')) + + for tag in "${tags[@]}"; do + for platform in "${platforms[@]}"; do + platform_tag=$(echo "${platform}" | tr '/' '-') + tag_to_delete="${tag}-${platform_tag}" + + echo "Deleting tag: ${tag_to_delete}" + echo "https://hub.docker.com/v2/repositories/$%7BDOCKER_USERNAME%7D/$%7BIMAGE_NAME%7D/tags/$%7Btag_to_delete%7D/" + + curl -X DELETE \ + -H "Authorization: Bearer ${{ secrets.DOCKER_HUB_ACCESS_TOKEN_DELETE }}" \ + "https://hub.docker.com/v2/repositories/$%7BDOCKER_USERNAME%7D/$%7BIMAGE_NAME%7D/tags/$%7Btag_to_delete%7D/" + done + done diff --git a/.github/workflows/macos-test.yml b/.github/workflows/macos-test.yml index 64a7687572..520de15171 100644 --- a/.github/workflows/macos-test.yml +++ b/.github/workflows/macos-test.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-13, macos-14] # TODO: macos-15: https://github.com/metacall/core/issues/530 + os: [macos-13, macos-14, macos-15] options: [ {build: debug, sanitizer: without-sanitizer}, {build: debug, sanitizer: address-sanitizer}, @@ -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 @@ -77,7 +81,7 @@ jobs: - name: Set up the environment run: sh ./tools/metacall-environment.sh $METACALL_INSTALL_OPTIONS env: - METACALL_INSTALL_OPTIONS: base python nodejs typescript java ruby wasm rpc file cobol go backtrace #netcore5 c rust rapidjson funchook swig pack # clangformat v8rep51 coverage + METACALL_INSTALL_OPTIONS: base python nodejs typescript java ruby wasm rpc file cobol go backtrace #netcore5 c rust rapidjson pack # clangformat v8rep51 coverage - name: Configure run: | @@ -89,13 +93,11 @@ jobs: - name: Build working-directory: ./build - # TODO: Remove the disable option for fork safe once funchook problem is solved run: | . .env - cmake -DOPTION_FORK_SAFE=OFF .. bash ../tools/metacall-build.sh $METACALL_BUILD_OPTIONS env: - METACALL_BUILD_OPTIONS: ${{ matrix.options.build }} tests + METACALL_BUILD_OPTIONS: ${{ matrix.options.build }} tests install macos-distributable: name: MacOS Distributable Dispatch @@ -112,7 +114,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: diff --git a/.github/workflows/release-nodejs.yml b/.github/workflows/release-nodejs.yml new file mode 100644 index 0000000000..da626217cc --- /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/**' + +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/.github/workflows/release-python.yml b/.github/workflows/release-python.yml index 52f6f4c881..a5f0c7de4f 100644 --- a/.github/workflows/release-python.yml +++ b/.github/workflows/release-python.yml @@ -4,7 +4,11 @@ on: push: branches: [ master, develop ] paths: - - 'source/ports/py_port/VERSION' + - 'source/ports/py_port/**' + +permissions: + id-token: write + contents: read concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 10baaf1e74..d2a0c31a43 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -1,11 +1,13 @@ 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' + - '.github/workflows/release-rust.yml' + - 'source/ports/rs_port/**' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -15,9 +17,44 @@ 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] # TODO: , 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 the Rust Port + working-directory: source/ports/rs_port + run: cargo build --verbose + + - name: Test the Rust Port + working-directory: source/ports/rs_port + run: cargo test --verbose + release: name: Release Rust Port runs-on: ubuntu-latest + needs: test + if: ${{ github.event_name != 'pull_request' }} steps: - name: Check out the repo uses: actions/checkout@v4 diff --git a/.github/workflows/windows-test.yml b/.github/workflows/windows-test.yml index c7af6e0eed..3518e6d4db 100644 --- a/.github/workflows/windows-test.yml +++ b/.github/workflows/windows-test.yml @@ -17,11 +17,12 @@ concurrency: jobs: windows-test: name: Windows MSVC Test - runs-on: windows-2019 # TODO: Implement matrix with windows 2019 and 2022 + runs-on: windows-${{ matrix.os }} strategy: fail-fast: false matrix: + os: [2022, 2025] options: [ {build: debug, sanitizer: without-sanitizer}, {build: debug, sanitizer: address-sanitizer}, @@ -48,7 +49,7 @@ jobs: - name: Set up the environment run: cmd.exe /c "powershell .\tools\metacall-environment.ps1 $Env:METACALL_INSTALL_OPTIONS" env: - METACALL_INSTALL_OPTIONS: python nodejs java ruby typescript wasm rpc file # netcore5 java c cobol rust rapidjson funchook swig pack # clangformat v8rep51 coverage + METACALL_INSTALL_OPTIONS: python nodejs java ruby typescript wasm rpc file # netcore5 java c cobol rust rapidjson pack # clangformat v8rep51 coverage - name: Configure run: | @@ -63,7 +64,7 @@ jobs: working-directory: ./build run: cmd.exe /c "powershell ..\tools\metacall-build.ps1 $Env:METACALL_BUILD_OPTIONS" env: - METACALL_BUILD_OPTIONS: ${{ matrix.options.build }} tests + METACALL_BUILD_OPTIONS: ${{ matrix.options.build }} tests install windows-distributable: name: Windows Distributable Dispatch diff --git a/CMakeLists.txt b/CMakeLists.txt index 6896e14f19..f543559e6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # A library for providing a foreing function interface calls. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ # # CMake version -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) # Include cmake modules @@ -241,6 +241,9 @@ else() endif() endif() +# Export compile commands +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # # CTest configuration # diff --git a/Dockerfile b/Dockerfile index 915d0f4a50..a81cfd453b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/LICENSE b/LICENSE index 2e591e57ad..d56ad81fad 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2016-2024 Vicente Eduardo Ferrer Garcia + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE index 64d3172e01..687413ccf2 100644 --- a/NOTICE +++ b/NOTICE @@ -19,9 +19,8 @@ All external code and licenses used by **METACALL** are always wrapped into plug - [2. Serials](#2-serials) - [2.1 RapidJSON](#21-rapidjson) - [3. Detours](#3-detours) - - [3.1 FuncHook](#31-funchook) + - [3.1 PLTHook](#31-plthook) - [4. Ports](#4-ports) - - [4.1 Swig](#41-swig) @@ -80,24 +79,10 @@ All external code and licenses used by **METACALL** are always wrapped into plug ## 3. Detours -### 3.1 FuncHook +### 3.1 PLTHook -| Software | License | -| :----------: | :-------------------------------------------------------------------------------------------------: | -| **FuncHook** | [GPLv2 or later with a GPL linking exception](https://github.com/kubo/funchook/blob/master/LICENSE) | +| Software | License | +| :----------: | :------------------------------------------------------------------------------------------: | +| **PLTHook** | [2-clause BSD-style license](https://github.com/metacall/plthook?tab=readme-ov-file#license) | ## 4. Ports - -### 4.1 Swig - -| Software | License | -| :------: | :-----: | -| **SWIG** | **∅** | - ->When SWIG is used as it is distributed by the SWIG developers, its output is not governed by SWIG's license (including the GPL). SWIG's output contains code from three sources: -> -> - code generated by SWIG, which is not governed by copyright; -> - code copied from the SWIG library which is permissively licensed to be redistributed without restriction; -> - code derived from the user's input, which may be governed by the license of the code supplied by the user. -> ->So, while the input supplied to SWIG may affect the license of SWIG's output (e.g. if the input code is licensed under a copyleft or proprietary license), SWIG's license does not affect the license of the output. This is consistent with the FSF's FAQ entries on this subject ([GPLOutput](http://www.gnu.org/licenses/gpl-faq.html#GPLOutput) and [WhatCaseIsOutputGPL](http://www.gnu.org/licenses/gpl-faq.html#WhatCaseIsOutputGPL)), because the SWIG code copied into the output by SWIG is not GPL-licensed. diff --git a/VERSION b/VERSION index 35864a97fe..6f16bd3257 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.7 \ No newline at end of file +0.9.15 \ No newline at end of file diff --git a/cmake/CMakeDebug.cmake b/cmake/CMakeDebug.cmake index 632183fa18..dd80a221b9 100644 --- a/cmake/CMakeDebug.cmake +++ b/cmake/CMakeDebug.cmake @@ -2,7 +2,7 @@ # CMake Debug Utilities by Parra Studios # CMake debugging utilities and inspection facilities. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/CheckCCompilerFlagStackSmashing.cmake b/cmake/CheckCCompilerFlagStackSmashing.cmake index 1662f40231..ea31ed5d77 100644 --- a/cmake/CheckCCompilerFlagStackSmashing.cmake +++ b/cmake/CheckCCompilerFlagStackSmashing.cmake @@ -2,7 +2,7 @@ # Compiler checker for stack smashing flags by Parra Studios # Tests if a defined stack smashing security flag is available. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/CheckCXXCompilerFlagStackSmashing.cmake b/cmake/CheckCXXCompilerFlagStackSmashing.cmake index eff0c6bfa2..9fa7f95891 100644 --- a/cmake/CheckCXXCompilerFlagStackSmashing.cmake +++ b/cmake/CheckCXXCompilerFlagStackSmashing.cmake @@ -2,7 +2,7 @@ # Compiler checker for stack smashing flags by Parra Studios # Tests if a defined stack smashing security flag is available. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/CompileOptions.cmake b/cmake/CompileOptions.cmake index f569a6c169..b3cd23a466 100644 --- a/cmake/CompileOptions.cmake +++ b/cmake/CompileOptions.cmake @@ -149,6 +149,72 @@ else() set(SANITIZER_COMPILE_DEFINITIONS) endif() +function(find_sanitizer NAME LINK_OPTION) + string(TOUPPER "${NAME}" NAME_UPPER) + set(SANITIZER_PROGRAM_CODE "int main() {return 0;}") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sanitizer_locate.cpp" "${SANITIZER_PROGRAM_CODE}") + + try_compile( + STATUS + ${PROJECT_OUTPUT_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/sanitizer_locate.cpp + OUTPUT_VARIABLE SANITIZER_COMPILER_OUTPUT + LINK_OPTIONS ${LINK_OPTION} + COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/sanitizer_locate + ) + + if(NOT STATUS) + message(FATAL_ERROR "Could not find location for lib${NAME}: ${SANITIZER_COMPILER_OUTPUT}") + return() + endif() + + file(GET_RUNTIME_DEPENDENCIES + EXECUTABLES ${CMAKE_CURRENT_BINARY_DIR}/sanitizer_locate + RESOLVED_DEPENDENCIES_VAR SANITIZER_PROGRAM_LIBRARIES + ) + + foreach(DEPENDENCY IN LISTS SANITIZER_PROGRAM_LIBRARIES) + string(FIND "${DEPENDENCY}" "${NAME}" POSITION) + if(POSITION GREATER -1) + set(LIB${NAME_UPPER}_PATH "${DEPENDENCY}" PARENT_SCOPE) + return() + endif() + endforeach() +endfunction() + +if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") + if(OPTION_BUILD_THREAD_SANITIZER) + find_sanitizer(tsan -fsanitize=thread) + set(SANITIZER_LIBRARIES_PATH + "${LIBTSAN_PATH}" + ) + elseif(OPTION_BUILD_MEMORY_SANITIZER) + set(SANITIZER_LIBRARIES_PATH) # TODO + elseif(OPTION_BUILD_ADDRESS_SANITIZER) + find_sanitizer(asan -fsanitize=address) + find_sanitizer(ubsan -fsanitize=undefined) + set(SANITIZER_LIBRARIES_PATH + "${LIBASAN_PATH}" + "${LIBUBSAN_PATH}" + ) + endif() +endif() + +if(SANITIZER_LIBRARIES_PATH) + if(PROJECT_OS_LINUX) + list(JOIN SANITIZER_LIBRARIES_PATH " " SANITIZER_LIBRARIES_PATH_JOINED) + set(TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES + "LD_PRELOAD=${SANITIZER_LIBRARIES_PATH_JOINED}" + ) + elseif(PROJECT_OS_FAMILY MATCHES "macos") + list(JOIN SANITIZER_LIBRARIES_PATH ":" SANITIZER_LIBRARIES_PATH_JOINED) + set(TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES + "DYLD_INSERT_LIBRARIES=${SANITIZER_LIBRARIES_PATH_JOINED}" + "DYLD_FORCE_FLAT_NAMESPACE=1" + ) + endif() +endif() + if((PROJECT_OS_WIN AND MSVC) OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # MSVC and Clang do not require to link manually the sanitizer libraries set(SANITIZER_LIBRARIES) @@ -253,14 +319,14 @@ if(WIN32 AND MSVC) add_compile_options(/Oy) # TODO: Disable runtime checks (not compatible with O2) - # foreach(FLAG_VAR + # foreach(COMPILER_FLAGS # CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE # CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO # CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE # CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO # ) - # string(REGEX REPLACE "/RTC[^ ]*" "" ${FLAG_VAR} "${${FLAG_VAR}}") - # endforeach(FLAG_VAR) + # string(REGEX REPLACE "/RTC[^ ]*" "" ${COMPILER_FLAGS} "${${COMPILER_FLAGS}}") + # endforeach(COMPILER_FLAGS) if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") # Enable debug symbols @@ -271,7 +337,6 @@ if(WIN32 AND MSVC) # Sanitizers if(OPTION_BUILD_THREAD_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) add_compile_options(/fsanitize=thread) - # add_compile_options(/fsanitize=undefined) add_link_options(/INCREMENTAL:NO) elseif(OPTION_BUILD_ADDRESS_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) add_compile_options(/fsanitize=address) @@ -282,6 +347,7 @@ if(WIN32 AND MSVC) add_compile_options(/fsanitize=leak) add_link_options(/INCREMENTAL:NO) endif() + endif() if (PROJECT_OS_FAMILY MATCHES "unix" OR PROJECT_OS_FAMILY MATCHES "macos") @@ -361,6 +427,55 @@ if (PROJECT_OS_FAMILY MATCHES "unix" OR PROJECT_OS_FAMILY MATCHES "macos") endif() endif() +macro(check_symbol_executable symbol binary_path result_var) + if(WIN32) + find_program(DUMPBIN_EXECUTABLE dumpbin) + if(NOT DUMPBIN_EXECUTABLE) + message(FATAL_ERROR "Trying to find symbol ${symbol} in ${binary_path} but dumpbin was not found") + endif() + execute_process( + COMMAND ${DUMPBIN_EXECUTABLE} /symbols ${binary_path} + OUTPUT_VARIABLE dumpbin_output + RESULT_VARIABLE dumpbin_result + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(FIND "${dumpbin_output}" symbol SYMBOL_FOUND) + if(NOT SYMBOL_FOUND EQUAL -1) + set(${result_var} TRUE PARENT_SCOPE) + else() + set(${result_var} FALSE PARENT_SCOPE) + endif() + else() + find_program(NM_EXECUTABLE nm) + if(NM_EXECUTABLE) + execute_process( + COMMAND ${NM_EXECUTABLE} -D ${binary_path} + OUTPUT_VARIABLE nm_output + RESULT_VARIABLE nm_result + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(FIND "${nm_output}" symbol SYMBOL_FOUND) + if(NOT SYMBOL_FOUND EQUAL -1) + set(${result_var} TRUE PARENT_SCOPE) + else() + set(${result_var} FALSE PARENT_SCOPE) + endif() + else() + message(FATAL_ERROR "Trying to find symbol ${symbol} in ${binary_path} but nm was not found") + endif() + endif() +endmacro() + +function(check_asan_executable binary_path result_var) + check_symbol_executable("__asan_init" "${binary_path}" ${result_var}) +endfunction() + +function(check_tsan_executable binary_path result_var) + check_symbol_executable("__tsan_init" "${binary_path}" ${result_var}) +endfunction() + # # Linker options # diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake index e363f5a58d..4a15b0efcb 100644 --- a/cmake/Coverage.cmake +++ b/cmake/Coverage.cmake @@ -2,7 +2,7 @@ # Coverage CMake support by Parra Studios # Cross-compiler code coverage utility. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindCobol.cmake b/cmake/FindCobol.cmake index 4a943d0744..c85a5cb466 100644 --- a/cmake/FindCobol.cmake +++ b/cmake/FindCobol.cmake @@ -2,7 +2,7 @@ # CMake Find GNU/Cobol by Parra Studios # CMake script to find GNU/Cobol compiler and runtime. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindCoreCLR.cmake b/cmake/FindCoreCLR.cmake index 1ae2a4455b..884d3c1132 100644 --- a/cmake/FindCoreCLR.cmake +++ b/cmake/FindCoreCLR.cmake @@ -2,7 +2,7 @@ # CMake Find CoreCLR NET Engine by Parra Studios # CMake script to find CoreCLR NET Engine. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindDotNET.cmake b/cmake/FindDotNET.cmake index 859b4977b6..57c2d4dc95 100644 --- a/cmake/FindDotNET.cmake +++ b/cmake/FindDotNET.cmake @@ -2,7 +2,7 @@ # CMake Find Dot NET Engine by Parra Studios # CMake script to find DotNET Engine. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindGBench.cmake b/cmake/FindGBench.cmake index 9584029791..74eacb0b8a 100644 --- a/cmake/FindGBench.cmake +++ b/cmake/FindGBench.cmake @@ -2,7 +2,7 @@ # CMake Find Google Benchmark by Parra Studios # CMake script to find Google Benchmark library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindJulia.cmake b/cmake/FindJulia.cmake index 3557748462..bf3c30d3b8 100644 --- a/cmake/FindJulia.cmake +++ b/cmake/FindJulia.cmake @@ -2,7 +2,7 @@ # CMake Find Julia Runtime by Parra Studios # CMake script to find Julia runtime. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindLibClang.cmake b/cmake/FindLibClang.cmake index 9b07a6b366..bbf4d2c25f 100644 --- a/cmake/FindLibClang.cmake +++ b/cmake/FindLibClang.cmake @@ -2,7 +2,7 @@ # CMake Find Clang library by Parra Studios # CMake script to find Clang C API library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindLibFFI.cmake b/cmake/FindLibFFI.cmake index b86cf7d8d3..313925b13e 100644 --- a/cmake/FindLibFFI.cmake +++ b/cmake/FindLibFFI.cmake @@ -2,7 +2,7 @@ # CMake Find Foreing Function Interface library by Parra Studios # CMake script to find FFI library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindLibGit2.cmake b/cmake/FindLibGit2.cmake new file mode 100644 index 0000000000..cb1c0cf0a1 --- /dev/null +++ b/cmake/FindLibGit2.cmake @@ -0,0 +1,82 @@ +# +# CMake Find LibGit2 Library by Parra Studios +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia +# + +# Find libgit2 library and include paths +# +# LibGit2_FOUND - True if LibGit2 was found +# LibGit2_INCLUDE_DIR - LibGit2 headers path +# LibGit2_VERSION - LibGit2 version +# LibGit2_VERSION_MAJOR - LibGit2 major version +# LibGit2_VERSION_MINOR - LibGit2 minor version +# LibGit2_VERSION_REVISION - LibGit2 patch version +# LibGit2_LIBRARY - LibGit2 shared library +# LibGit2_LIBRARY_DIR - LibGit2 shared library folder +# + +# Prevent vervosity if already included +if(LibGit2_LIBRARY) + set(LibGit2_FIND_QUIETLY TRUE) +endif() + +# Include package manager +include(FindPackageHandleStandardArgs) + +# Find via PkgConfig +find_package(PkgConfig QUIET) +pkg_check_modules(PKG_GIT2 QUIET libgit2) + +if(NOT PKG_GIT2_FOUND) + return() +endif() + +if(NOT LibGit2_DEFINITIONS) + set(LibGit2_DEFINITIONS ${PKG_GIT2_CFLAGS_OTHER}) +endif() + +if(NOT LibGit2_INCLUDE_DIR) + find_path(LibGit2_INCLUDE_DIR + NAMES git2.h + HINTS ${PKG_GIT2_INCLUDE_DIRS} + ) +endif() + +if(NOT LibGit2_VERSION AND LibGit2_INCLUDE_DIR) + file(STRINGS "${LibGit2_INCLUDE_DIR}/git2/version.h" LibGit2_VERSION_MAJOR REGEX "^#define LIBGIT2_VER_MAJOR +([0-9]+)") + string(REGEX MATCH "([0-9]+)$" LibGit2_VERSION_MAJOR "${LibGit2_VERSION_MAJOR}") + + file(STRINGS "${LibGit2_INCLUDE_DIR}/git2/version.h" LibGit2_VERSION_MINOR REGEX "^#define LIBGIT2_VER_MINOR +([0-9]+)") + string(REGEX MATCH "([0-9]+)$" LibGit2_VERSION_MINOR "${LibGit2_VERSION_MINOR}") + + file(STRINGS "${LibGit2_INCLUDE_DIR}/git2/version.h" LibGit2_VERSION_REVISION REGEX "^#define LIBGIT2_VER_REVISION +([0-9]+)") + string(REGEX MATCH "([0-9]+)$" LibGit2_VERSION_REVISION "${LibGit2_VERSION_REVISION}") + + set(LibGit2_VERSION "${LibGit2_VERSION_MAJOR}.${LibGit2_VERSION_MINOR}.${LibGit2_VERSION_REVISION}") +endif() + +if(NOT LibGit2_LIBRARY) + find_library(LibGit2_LIBRARY + NAMES git2 + HINTS ${PKG_GIT2_LIBRARY_DIRS} + ) +endif() + +set(LibGit2_LIBRARIES ${LibGit2_LIBRARY}) +set(LibGit2_INCLUDE_DIRS ${LibGit2_INCLUDE_DIR}) +get_filename_component(LibGit2_LIBRARY_DIR ${LibGit2_LIBRARY} DIRECTORY) + +# Define package +find_package_handle_standard_args(LibGit2 + FOUND_VAR + LibGit2_FOUND + REQUIRED_VARS + LibGit2_LIBRARY + LibGit2_LIBRARY_DIR + LibGit2_INCLUDE_DIR + LibGit2_INCLUDE_DIRS + VERSION_VAR + LibGit2_VERSION +) + +mark_as_advanced(LibGit2_LIBRARY LibGit2_LIBRARY_DIR LibGit2_INCLUDE_DIR) diff --git a/cmake/FindLibTCC.cmake b/cmake/FindLibTCC.cmake index c75c694196..83c2e4ac59 100644 --- a/cmake/FindLibTCC.cmake +++ b/cmake/FindLibTCC.cmake @@ -2,7 +2,7 @@ # CMake Find Tiny C Compiler library by Parra Studios # CMake script to find TCC library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindMetaCall.cmake b/cmake/FindMetaCall.cmake index f25310921e..f974e9509d 100644 --- a/cmake/FindMetaCall.cmake +++ b/cmake/FindMetaCall.cmake @@ -2,7 +2,7 @@ # CMake Find MetaCall library by Parra Studios # CMake script to find and include MetaCall library for development. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindNPM.cmake b/cmake/FindNPM.cmake index 1cdcda92d0..2a61990e25 100644 --- a/cmake/FindNPM.cmake +++ b/cmake/FindNPM.cmake @@ -2,7 +2,7 @@ # CMake Find NPM by Parra Studios # CMake script to find NodeJS Package Manager. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindNodeJS.cmake b/cmake/FindNodeJS.cmake index a4c7db2928..6cea42bf48 100644 --- a/cmake/FindNodeJS.cmake +++ b/cmake/FindNodeJS.cmake @@ -1,6 +1,6 @@ # # CMake Find NodeJS JavaScript Runtime by Parra Studios -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Find NodeJS executable and include paths @@ -453,7 +453,9 @@ if(NOT NodeJS_LIBRARY) endif() # Check for Visual Studio Version and configure the build command - if(MSVC_VERSION GREATER 1916) + if(MSVC_VERSION GREATER_EQUAL 1930) + set(NodeJS_MSVC_VER vs2022) + elseif(MSVC_VERSION GREATER_EQUAL 1920) set(NodeJS_MSVC_VER vs2019) elseif(MSVC_VERSION GREATER 1900) set(NodeJS_MSVC_VER vs2017) diff --git a/cmake/FindPatchelf.cmake b/cmake/FindPatchelf.cmake index af0dd619c6..044cd412d0 100644 --- a/cmake/FindPatchelf.cmake +++ b/cmake/FindPatchelf.cmake @@ -2,7 +2,7 @@ # CMake Find Patchelf by Parra Studios # CMake script to find Patchelf executable. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindRapidJSON.cmake b/cmake/FindRapidJSON.cmake index af111fafed..26b0d6b1e1 100644 --- a/cmake/FindRapidJSON.cmake +++ b/cmake/FindRapidJSON.cmake @@ -2,7 +2,7 @@ # CMake Find RapidJSON by Parra Studios # CMake script to find RapidJSON library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindRust.cmake b/cmake/FindRust.cmake index 58e61876c9..c9ef316aa2 100644 --- a/cmake/FindRust.cmake +++ b/cmake/FindRust.cmake @@ -2,7 +2,7 @@ # CMake Find Rust by Parra Studios # CMake script to find Rust compiler and tools. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindSpiderMonkey.cmake b/cmake/FindSpiderMonkey.cmake index 8da1d52549..a952c9e4e9 100644 --- a/cmake/FindSpiderMonkey.cmake +++ b/cmake/FindSpiderMonkey.cmake @@ -2,7 +2,7 @@ # CMake Find Mozilla SpiderMonkey JavaScript Engine by Parra Studios # CMake script to find Mozilla SpiderMonkey Javascript Engine. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindV8.cmake b/cmake/FindV8.cmake index a995b1d3c7..aedb8a8d7d 100644 --- a/cmake/FindV8.cmake +++ b/cmake/FindV8.cmake @@ -2,7 +2,7 @@ # CMake Find V8 Google JavaScript Engine by Parra Studios # CMake script to find V8 JavaScript Engine. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/FindWasmtime.cmake b/cmake/FindWasmtime.cmake index a68272c0c2..bf086293a9 100644 --- a/cmake/FindWasmtime.cmake +++ b/cmake/FindWasmtime.cmake @@ -1,6 +1,6 @@ # # CMake Find Wasmtime WebAssembly Runtime by Parra Studios -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Find Wasmtime library and include paths diff --git a/cmake/FindZig.cmake b/cmake/FindZig.cmake index 286ec5f53c..cb2764032c 100644 --- a/cmake/FindZig.cmake +++ b/cmake/FindZig.cmake @@ -2,7 +2,7 @@ # CMake Find Zig by Parra Studios # CMake script to find Zig compiler and tools. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/InstallGBench.cmake b/cmake/InstallGBench.cmake index 5d6956a537..ccf3073d7a 100644 --- a/cmake/InstallGBench.cmake +++ b/cmake/InstallGBench.cmake @@ -2,7 +2,7 @@ # CMake Install Google Benchmark by Parra Studios # CMake script to install Google Benchmark library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/InstallGTest.cmake b/cmake/InstallGTest.cmake index f6d025c795..45fdf569c9 100644 --- a/cmake/InstallGTest.cmake +++ b/cmake/InstallGTest.cmake @@ -2,7 +2,7 @@ # CMake Install Google Test by Parra Studios # CMake script to install Google Test library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ if(NOT GTEST_FOUND OR USE_BUNDLED_GTEST) if(NOT GTEST_VERSION OR USE_BUNDLED_GTEST) - set(GTEST_VERSION 1.11.0) + set(GTEST_VERSION 1.16.0) endif() find_package(Threads REQUIRED) @@ -35,10 +35,22 @@ if(NOT GTEST_FOUND OR USE_BUNDLED_GTEST) set(GTEST_DISABLE_PTHREADS OFF) endif() + if(MSVC AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) + if(OPTION_BUILD_THREAD_SANITIZER) + set(SANITIZER_FLAGS -DCMAKE_CXX_FLAGS=/fsanitize=thread -DCMAKE_C_FLAGS=/fsanitize=thread) + endif() + if(OPTION_BUILD_ADDRESS_SANITIZER) + set(SANITIZER_FLAGS -DCMAKE_CXX_FLAGS=/fsanitize=address -DCMAKE_C_FLAGS=/fsanitize=address) + endif() + if(OPTION_BUILD_MEMORY_SANITIZER) + set(SANITIZER_FLAGS -DCMAKE_CXX_FLAGS="/fsanitize=memory /fsanitize=leak" -DCMAKE_C_FLAGS="/fsanitize=memory /fsanitize=leak") + endif() + endif() + # Import Google Test Framework ExternalProject_Add(google-test-depends GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-${GTEST_VERSION} + GIT_TAG v${GTEST_VERSION} CMAKE_ARGS -Dgtest_build_samples=OFF -Dgtest_build_tests=OFF @@ -48,6 +60,7 @@ if(NOT GTEST_FOUND OR USE_BUNDLED_GTEST) -DINSTALL_GTEST=OFF -DBUILD_GMOCK=ON -Dgmock_build_tests=OFF + ${SANITIZER_FLAGS} PREFIX "${CMAKE_CURRENT_BINARY_DIR}" UPDATE_COMMAND "" INSTALL_COMMAND "" @@ -65,17 +78,11 @@ if(NOT GTEST_FOUND OR USE_BUNDLED_GTEST) set(GTEST_LIB_SUFFIX "lib") set(GTEST_LIBS_DIR "${binary_dir}/lib/${CMAKE_BUILD_TYPE}") set(GMOCK_LIBS_DIR "${binary_dir}/lib/${CMAKE_BUILD_TYPE}") - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(GTEST_LIB_DEBUG "d") - else() - set(GTEST_LIB_DEBUG "") - endif() else() set(GTEST_LIB_PREFIX "lib") set(GTEST_LIB_SUFFIX "a") set(GTEST_LIBS_DIR "${binary_dir}/lib") set(GMOCK_LIBS_DIR "${binary_dir}/lib") - set(GTEST_LIB_DEBUG "") endif() # Define Paths @@ -85,11 +92,11 @@ if(NOT GTEST_FOUND OR USE_BUNDLED_GTEST) ) set(GTEST_LIBRARY - "${GTEST_LIBS_DIR}/${GTEST_LIB_PREFIX}gtest${GTEST_LIB_DEBUG}.${GTEST_LIB_SUFFIX}" + "${GTEST_LIBS_DIR}/${GTEST_LIB_PREFIX}gtest.${GTEST_LIB_SUFFIX}" ) set(GMOCK_LIBRARY - "${GMOCK_LIBS_DIR}/${GTEST_LIB_PREFIX}gmock${GTEST_LIB_DEBUG}.${GTEST_LIB_SUFFIX}" + "${GMOCK_LIBS_DIR}/${GTEST_LIB_PREFIX}gmock.${GTEST_LIB_SUFFIX}" ) set(GTEST_LIBRARIES diff --git a/cmake/InstallLibTCC.cmake b/cmake/InstallLibTCC.cmake index 096f447c9b..23a780e264 100644 --- a/cmake/InstallLibTCC.cmake +++ b/cmake/InstallLibTCC.cmake @@ -2,7 +2,7 @@ # CMake Install Tiny C Compiler by Parra Studios # CMake script to install TCC library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -84,7 +84,7 @@ elseif(PROJECT_OS_FAMILY STREQUAL macos) # AddressSanitizer can not provide additional info. # SUMMARY: AddressSanitizer: BUS (libsystem_c.dylib:x86_64+0x3647db0f) in off32 - set(LIBTCC_CONFIGURE ./configure --prefix=${LIBTCC_INSTALL_PREFIX} ${LIBTCC_DEBUG} --enable-cross) # --disable-static + set(LIBTCC_CONFIGURE ./configure --prefix=${LIBTCC_INSTALL_PREFIX} ${LIBTCC_DEBUG}) # --disable-static elseif(PROJECT_OS_FAMILY STREQUAL win32) if(PROJECT_OS_NAME STREQUAL MinGW) set(LIBTCC_CONFIGURE ./configure --prefix=${LIBTCC_INSTALL_PREFIX} ${LIBTCC_DEBUG} --config-mingw32 --disable-static) @@ -125,7 +125,7 @@ else() endif() set(LIBTCC_TARGET libtcc-depends) -set(LIBTCC_COMMIT_SHA "afc1362") +set(LIBTCC_COMMIT_SHA "6ec4a10") if(PROJECT_OS_FAMILY STREQUAL macos) # TODO: --disable-static is not working on MacOS, this should be reported or further investigated, remove this when it is solved set(LIBTTC_LIBRARY_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}tcc${CMAKE_STATIC_LIBRARY_SUFFIX}") @@ -146,7 +146,7 @@ set(LIBTTC_RUNTIME_FILES ExternalProject_Add(${LIBTCC_TARGET} DOWNLOAD_NAME tinycc.tar.gz URL https://github.com/metacall/tinycc/archive/${LIBTCC_COMMIT_SHA}.tar.gz - URL_MD5 5582b17ee5848aeec28bee13773843f7 + URL_MD5 1d25d1a07a39c6d6671b7221d5286dc1 CONFIGURE_COMMAND ${LIBTCC_CONFIGURE} BUILD_COMMAND ${LIBTCC_BUILD} BUILD_IN_SOURCE true diff --git a/cmake/InstallPatchelf.cmake b/cmake/InstallPatchelf.cmake index a001e136df..72b44a952d 100644 --- a/cmake/InstallPatchelf.cmake +++ b/cmake/InstallPatchelf.cmake @@ -2,7 +2,7 @@ # CMake Find Patchelf by Parra Studios # CMake script to find Patchelf executable. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/InstallRapidJSON.cmake b/cmake/InstallRapidJSON.cmake index 8b4bc960d0..f90dfc4a4e 100644 --- a/cmake/InstallRapidJSON.cmake +++ b/cmake/InstallRapidJSON.cmake @@ -2,7 +2,7 @@ # CMake Install RapidJSON by Parra Studios # CMake script to install RapidJSON library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,23 +24,21 @@ if(NOT RAPIDJSON_FOUND OR USE_BUNDLED_RAPIDJSON) if(NOT RAPIDJSON_VERSION OR USE_BUNDLED_RAPIDJSON) - set(RAPIDJSON_VERSION ab1842a2dae061284c0a62dca1cc6d5e7e37e346) + set(RAPIDJSON_VERSION 24b5e7a8b27f42fa16b96fc70aade9106cf7102f) endif() ExternalProject_Add(rapid-json-depends - GIT_REPOSITORY "https://github.com/Tencent/rapidjson.git" - GIT_TAG "${RAPIDJSON_VERSION}" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX= - -DRAPIDJSON_BUILD_DOC=Off - -DRAPIDJSON_BUILD_EXAMPLES=Off - -DRAPIDJSON_BUILD_TESTS=Off - TEST_COMMAND "" + GIT_REPOSITORY "https://github.com/Tencent/rapidjson.git" + GIT_TAG "${RAPIDJSON_VERSION}" + BUILD_COMMAND "" + CONFIGURE_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" ) - ExternalProject_Get_Property(rapid-json-depends INSTALL_DIR) + ExternalProject_Get_Property(rapid-json-depends SOURCE_DIR) - set(RAPIDJSON_ROOT_DIR ${INSTALL_DIR}) + set(RAPIDJSON_ROOT_DIR ${SOURCE_DIR}) set(RAPIDJSON_INCLUDE_DIRS ${RAPIDJSON_ROOT_DIR}/include) set(RAPIDJSON_FOUND TRUE) diff --git a/cmake/Portability.cmake b/cmake/Portability.cmake index 75dc09c2f6..556427b187 100644 --- a/cmake/Portability.cmake +++ b/cmake/Portability.cmake @@ -2,7 +2,7 @@ # Portability CMake support by Parra Studios # Cross-platform and architecture detection utility. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -146,11 +146,10 @@ set(PROJECT_ARCH_NAME ${CMAKE_SYSTEM_PROCESSOR}) # 32 or 64 bit Linux if(PROJECT_OS_LINUX) - if(${PROJECT_ARCH_NAME} STREQUAL "x86") + if (${PROJECT_ARCH_NAME} MATCHES "^(x86|i[3-6]86|x86_64)$" AND "${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") set(PROJECT_ARCH_32BIT TRUE BOOL INTERNAL) - endif() - - if(${PROJECT_ARCH_NAME} MATCHES "(x86_64)|(amd64)|(AMD64)") + set(PROJECT_ARCH_X86 TRUE BOOL INTERNAL) + elseif(${PROJECT_ARCH_NAME} MATCHES "(x86_64)|(amd64)|(AMD64)") set(PROJECT_ARCH_64BIT TRUE BOOL INTERNAL) set(PROJECT_ARCH_AMD64 TRUE BOOL INTERNAL) elseif(${PROJECT_ARCH_NAME} STREQUAL "aarch64") @@ -162,6 +161,7 @@ if(PROJECT_OS_LINUX) set(PROJECT_ARCH_64BIT TRUE BOOL INTERNAL) endif() + # Verify the architecture is correct if(PROJECT_ARCH_32BIT) if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4") message(STATUS "Linux ${PROJECT_ARCH_NAME} 32bit detected") @@ -183,7 +183,7 @@ endif() if(NOT PROJECT_ARCH_32BIT AND NOT PROJECT_ARCH_64BIT) if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4") message(STATUS "32bit architecture ${PROJECT_ARCH_NAME} detected") - set(PROJECT_ARCH_32BIT TRUE BOOL INTERNAL) + set(PROJECT_ARCH_32BIT TRUE BOOL INTERNAL) if(PROJECT_OS_WIN) set(WINXBITS Win32) @@ -191,7 +191,7 @@ if(NOT PROJECT_ARCH_32BIT AND NOT PROJECT_ARCH_64BIT) elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") message(STATUS "64bit architecture ${PROJECT_ARCH_NAME} detected") - set(PROJECT_ARCH_64BIT TRUE BOOL INTERNAL) + set(PROJECT_ARCH_64BIT TRUE BOOL INTERNAL) if(PROJECT_OS_WIN) set(WINXBITS Win64) diff --git a/cmake/ScriptProject.cmake b/cmake/ScriptProject.cmake index b078526fe8..fb7d138355 100644 --- a/cmake/ScriptProject.cmake +++ b/cmake/ScriptProject.cmake @@ -2,7 +2,7 @@ # Script project generator by Parra Studios # Generates a script project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/SecurityFlags.cmake b/cmake/SecurityFlags.cmake index 515dc6f85c..b31ccbbf7d 100644 --- a/cmake/SecurityFlags.cmake +++ b/cmake/SecurityFlags.cmake @@ -2,7 +2,7 @@ # Compiler and linker options for hardening flags by Parra Studios # Enables hardening security flags if available. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/TestEnvironmentVariables.cmake b/cmake/TestEnvironmentVariables.cmake index 43189a72eb..1255f2bb46 100644 --- a/cmake/TestEnvironmentVariables.cmake +++ b/cmake/TestEnvironmentVariables.cmake @@ -2,7 +2,7 @@ # Test Environment Variables by Parra Studios # Utility for defining cross-platform environment variables in tests. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmake/Warnings.cmake b/cmake/Warnings.cmake index 5c9b44da73..23f057afd2 100644 --- a/cmake/Warnings.cmake +++ b/cmake/Warnings.cmake @@ -2,7 +2,7 @@ # Cross-compiler warning utility by Parra Studios # Utility to enable cross-compiler warnings. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ if(WARNINGS_ENABLED) # Define C compiler warning flags if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") + # TODO: Uncomment the rest of the warnings, enable Weverything for clang add_compile_options(-Wall) add_compile_options(-Wextra) add_compile_options(-Wunused) @@ -85,7 +86,7 @@ if(WARNINGS_ENABLED) string(REPLACE "/W1" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") string(REPLACE "/W2" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") string(REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /Wall") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") # /Wall set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CTR_NONSTDC_NO_WARNINGS=1") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CTR_SECURE_NO_WARNINGS=1") set(WARNINGS_C_AVAILABLE 1) @@ -105,7 +106,7 @@ if(WARNINGS_ENABLED) string(REPLACE "/W1" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/W2" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") # /Wall set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _CTR_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _CTR_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _CTR_NONSTDC_NO_WARNINGS=1") diff --git a/deploy/packages/postinst b/deploy/packages/postinst index d798c724d0..8ae7a6fa6c 100755 --- a/deploy/packages/postinst +++ b/deploy/packages/postinst @@ -4,7 +4,7 @@ # MetaCall Dependencies Bash Script by Parra Studios # Remove all packages and unused data from MetaCall building and testing. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/docker-compose.cache.yml b/docker-compose.cache.yml index 231525f1c2..63b1b455c7 100644 --- a/docker-compose.cache.yml +++ b/docker-compose.cache.yml @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker compose infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/docker-compose.platform.yml b/docker-compose.platform.yml deleted file mode 100644 index 46b3b08256..0000000000 --- a/docker-compose.platform.yml +++ /dev/null @@ -1,37 +0,0 @@ -# -# MetaCall Library by Parra Studios -# Docker compose infrastructure for MetaCall. -# -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia -# -# 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. -# - -version: "3.7" - -services: - deps: - image: metacall/core:deps - platform: ${METACALL_PLATFORM} - - dev: - image: metacall/core:dev - platform: ${METACALL_PLATFORM} - - runtime: - image: metacall/core:runtime - platform: ${METACALL_PLATFORM} - - cli: - image: metacall/core:cli - platform: ${METACALL_PLATFORM} diff --git a/docker-compose.sh b/docker-compose.sh index 9c075acf8b..e254cb103e 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -4,7 +4,7 @@ # MetaCall Build Bash Script by Parra Studios # Build and install bash script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -206,17 +206,33 @@ sub_platform() { exit 1 fi + # Initialize QEMU for Buildkit + docker run --rm --privileged tonistiigi/binfmt --install all + + # Debian in Docker Hub does not support LoongArch64 yet, let's use official LoongArch repository instead + if [ "$METACALL_PLATFORM" = "linux/loong64" ]; then + source .env + export METACALL_BASE_IMAGE="ghcr.io/loong64/${METACALL_BASE_IMAGE}" + fi + + # Generate the docker compose file with all .env variables substituted (bake seems not to support this) + $DOCKER_COMPOSE -f docker-compose.yml config &> docker-compose.bake.yml + + # Build with Bake, so the image can be loaded into local docker context ln -sf tools/deps/.dockerignore .dockerignore - $DOCKER_COMPOSE -f docker-compose.yml -f docker-compose.platform.yml build deps + docker buildx bake -f docker-compose.bake.yml --set *.platform="${METACALL_PLATFORM}" --load deps ln -sf tools/dev/.dockerignore .dockerignore - $DOCKER_COMPOSE -f docker-compose.yml -f docker-compose.platform.yml build dev + docker buildx bake -f docker-compose.bake.yml --set *.platform="${METACALL_PLATFORM}" --load dev ln -sf tools/runtime/.dockerignore .dockerignore - $DOCKER_COMPOSE -f docker-compose.yml -f docker-compose.platform.yml build runtime + docker buildx bake -f docker-compose.bake.yml --set *.platform="${METACALL_PLATFORM}" --load runtime ln -sf tools/cli/.dockerignore .dockerignore - $DOCKER_COMPOSE -f docker-compose.yml -f docker-compose.platform.yml build cli + docker buildx bake -f docker-compose.bake.yml --set *.platform="${METACALL_PLATFORM}" --load cli + + # Delete temporal docker compose file + rm -rf docker-compose.bake.yml } # Push MetaCall Docker Compose diff --git a/docker-compose.test.yml b/docker-compose.test.yml index db095b5334..5802aeef51 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker compose infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,10 +25,10 @@ services: build: args: METACALL_BUILD_TYPE: ${METACALL_BUILD_TYPE} - METACALL_INSTALL_OPTIONS: base python ruby netcore7 nodejs typescript file rpc wasm java c cobol go rust rapidjson funchook swig pack backtrace sandbox ${METACALL_BUILD_COVERAGE} # clangformat v8rep51 + METACALL_INSTALL_OPTIONS: base python ruby netcore8 nodejs typescript file rpc wasm java c cobol go rust rapidjson pack backtrace sandbox ${METACALL_BUILD_COVERAGE} # clangformat v8rep51 dev: image: metacall/core:dev build: args: METACALL_BUILD_TYPE: ${METACALL_BUILD_TYPE} - METACALL_BUILD_OPTIONS: ${METACALL_BUILD_SANITIZER} python ruby netcore7 nodejs typescript file rpc wasm java c cobol go rust examples tests scripts ports install pack sandbox benchmarks ${METACALL_BUILD_COVERAGE} # v8 + METACALL_BUILD_OPTIONS: ${METACALL_BUILD_SANITIZER} python ruby netcore8 nodejs typescript file rpc wasm java c cobol go rust examples tests scripts ports install pack sandbox benchmarks ${METACALL_BUILD_COVERAGE} # v8 diff --git a/docker-compose.yml b/docker-compose.yml index d7383d6548..1c1997b138 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker compose infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,13 +17,12 @@ # limitations under the License. # -version: "3.7" - services: deps: image: metacall/core:deps container_name: metacall_core_deps build: + network: "host" context: . dockerfile: tools/deps/Dockerfile args: @@ -31,7 +30,7 @@ services: METACALL_PATH: $METACALL_PATH METACALL_TOOLS_PATH: $METACALL_PATH/tools METACALL_BUILD_TYPE: $METACALL_BUILD_TYPE - METACALL_INSTALL_OPTIONS: base python ruby nodejs typescript file rpc rapidjson funchook swig pack backtrace # clangformat v8rep51 coverage + METACALL_INSTALL_OPTIONS: base python ruby nodejs typescript file rpc rapidjson pack backtrace # clangformat v8rep51 coverage environment: DEBIAN_FRONTEND: noninteractive # Work around https://github.com/dotnet/cli/issues/1582 until Docker releases a @@ -48,6 +47,7 @@ services: image: metacall/core:dev container_name: metacall_core_dev build: + network: "host" context: . dockerfile: tools/dev/Dockerfile args: @@ -64,15 +64,13 @@ 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 - depends_on: - - deps runtime: image: metacall/core:runtime container_name: metacall_core_runtime build: + network: "host" context: . dockerfile: tools/runtime/Dockerfile args: @@ -89,15 +87,13 @@ 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 - depends_on: - - dev cli: image: metacall/core:cli container_name: metacall_core_cli build: + network: "host" context: . dockerfile: tools/cli/Dockerfile environment: @@ -110,8 +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 - depends_on: - - dev - - runtime diff --git a/docs/README.md b/docs/README.md index ff4002b4ba..55c101c5cd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -66,7 +66,7 @@ Use the [installer](https://github.com/metacall/install) and try [some examples] - [5.3.2.1 MetaCall](#5321-metacall) - [5.3.2.2 RapidJSON](#5322-rapidjson) - [5.3.3 Detours](#533-detours) - - [5.3.3.1 FuncHook](#5331-funchook) + - [5.3.3.1 PLTHook](#5331-plthook) - [5.4 Ports](#54-ports) - [5.5 Serialization](#55-serialization) - [5.6 Memory Layout](#56-memory-layout) @@ -116,7 +116,7 @@ This section describes all programming languages that **METACALL** allows to loa | [Java](https://www.java.com) | [JVM](https://en.wikipedia.org/wiki/Java_virtual_machine) | **>=11** | java | | [WebAssembly](https://webassembly.org/) | [Wasmtime](https://github.com/bytecodealliance/wasmtime) | **>= 0.27 <= 8.0.1** | wasm | | [C]() | [libclang](https://clang.llvm.org/doxygen/group__CINDEX.html) - [Tiny C Compiler](https://bellard.org/tcc/) - [libffi](http://sourceware.org/libffi/) | **>=12** - **>=2021-10-30** - **>=3.2** | c | -| [Rust](https://www.rust-lang.org/) | [rustc](https://doc.rust-lang.org/rustc/what-is-rustc.html) - [libffi](http://sourceware.org/libffi/) | **nightly-2021-12-04** | rs | +| [Rust](https://www.rust-lang.org/) | [rustc](https://doc.rust-lang.org/rustc/what-is-rustc.html) - [libffi](http://sourceware.org/libffi/) | **nightly-2021-12-04** | rs | - Languages and run-times under construction: @@ -251,7 +251,7 @@ The environment variables are optional, in case you want to modify default paths - [`detours`](/source/detours) implement the [`detour`](/source/detour) interface by using a plugin architecture. The current list of available detour plugins is the following one. - - [`funchook_detour`](/source/detours/funchook_detour) implemented by means of FuncHook library. + - [`plthook_detour`](/source/detours/plthook_detour) implemented by means of PLTHook library. - [`dynlink`](/source/dynlink) implements a cross-platform method to dynamically load libraries. It is used to dynamically load plugins into **METACALL**. @@ -499,7 +499,7 @@ A loader must implement it to be considered a valid loader. #### 5.3.3 Detours -##### 5.3.3.1 FuncHook +##### 5.3.3.1 PLTHook ### 5.4 Ports @@ -663,11 +663,11 @@ It is possible to enable or disable concrete loaders, script, ports, serials or | Build Option Prefix | Build Option Suffix | | :-----------------------: | --------------------------------------------------------------------- | -| **OPTION*BUILD_LOADERS*** | `C` `JS` `CS` `MOCK` `PY` `JSM` `NODE` `RB` `FILE` | -| **OPTION*BUILD_SCRIPTS*** | `C` `CS` `JS` `NODE` `PY` `RB` `JAVA` | -| **OPTION*BUILD_SERIALS*** | `METACALL` `RAPID_JSON` | -| **OPTION*BUILD_DETOURS*** | `FUNCHOOK` | -| **OPTION*BUILD_PORTS*** | `CS` `CXX` `D` `GO` `JAVA` `JS` `LUA` `NODE` `PHP` `PL` `PY` `R` `RB` | +| **OPTION_BUILD_LOADERS_*** | `C` `JS` `CS` `MOCK` `PY` `JSM` `NODE` `RB` `FILE` | +| **OPTION_BUILD_SCRIPTS_*** | `C` `CS` `JS` `NODE` `PY` `RB` `JAVA` | +| **OPTION_BUILD_SERIALS_*** | `METACALL` `RAPID_JSON` | +| **OPTION_BUILD_DETOURS_*** | `PLTHOOK` | +| **OPTION_BUILD_PORTS_*** | `CS` `CXX` `D` `GO` `JAVA` `JS` `LUA` `NODE` `PHP` `PL` `PY` `R` `RB` | To format the entire C/C++ codebase use: @@ -740,12 +740,12 @@ Click the button below. A workspace with all required environments will be creat The following platforms and architectures have been tested and are known to work correctly with all plugins of **METACALL**. -| Operative System | Architecture | Compiler | -| :--------------: | :-----------------: | :---------: | -| **`ubuntu`** | **`amd64`** | **`gcc`** | -| **`debian`** | **`amd64`** | **`gcc`** | -| **`debian`** | **`amd64`** | **`clang`** | -| **`windows`** | **`x86`** **`x64`** | **`msvc`** | +| Operative System | Architecture | Compiler | +| :--------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :---------: | +| **`ubuntu`** | **`amd64`** | **`gcc`** | +| **`debian`** | **`amd64`** **`amd64/v2`** **`amd64/v3`** **`386`** **`arm64`** **`riscv64`** **`ppc64le`** **`arm/v7`** **`arm/v6`** **`loong64`** | **`gcc`** | +| **`macos`** | **`amd64`** **`arm64`** | **`clang`** | +| **`windows`** | **`x86`** **`x64`** | **`msvc`** | ### 7.1 Docker Support @@ -862,13 +862,14 @@ Where `script.js` is a script contained in host folder `$HOME/metacall` that wil | :-----------------: | :--------------------------------------------------: | | **`ubuntu-latest`** | https://metacall.github.io/core/bench/ubuntu-latest/ | | **`macos-latest`** | https://metacall.github.io/core/bench/macos-latest/ | -| **`windows-2019`** | https://metacall.github.io/core/bench/windows-2019/ | +| **`windows-2022`** | https://metacall.github.io/core/bench/windows-2022/ | +| **`windows-2025`** | https://metacall.github.io/core/bench/windows-2025/ | ## 9. License **METACALL** is licensed under **[Apache License Version 2.0](/LICENSE)**. -> Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <> +> Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <> > > Licensed under the Apache License, Version 2.0 (the "License"); > you may not use this file except in compliance with the License. diff --git a/metacall-config-version.cmake.in b/metacall-config-version.cmake.in index c26ac86e96..a25c169f21 100644 --- a/metacall-config-version.cmake.in +++ b/metacall-config-version.cmake.in @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # A library for providing a foreing function interface calls. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/metacall-config.cmake.in b/metacall-config.cmake.in index b7f9f5b163..eb193eed48 100644 --- a/metacall-config.cmake.in +++ b/metacall-config.cmake.in @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # A library for providing a foreing function interface calls. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 13cb953f5a..b7c1e402b9 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} @@ -79,12 +71,13 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Default definitions # -add_definitions( - -DCONFIGURATION_INSTALL_PATH=\"${CMAKE_INSTALL_PREFIX}/${INSTALL_DATA}/configurations/global.json\" - -DSERIAL_LIBRARY_INSTALL_PATH=\"${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}\" - -DLOADER_LIBRARY_INSTALL_PATH=\"${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}\" - -DDETOUR_LIBRARY_INSTALL_PATH=\"${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}\" - -DPORT_LIBRARY_INSTALL_PATH=\"${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}\" +set(DEFAULT_COMPILE_DEFINITIONS + ${DEFAULT_COMPILE_DEFINITIONS} + CONFIGURATION_INSTALL_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_DATA}/configurations/global.json" + SERIAL_LIBRARY_INSTALL_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}" + LOADER_LIBRARY_INSTALL_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}" + DETOUR_LIBRARY_INSTALL_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}" + PORT_LIBRARY_INSTALL_PATH="${CMAKE_INSTALL_PREFIX}/${INSTALL_SHARED}" ) # diff --git a/source/adt/CMakeLists.txt b/source/adt/CMakeLists.txt index 122513f58a..6083509df2 100644 --- a/source/adt/CMakeLists.txt +++ b/source/adt/CMakeLists.txt @@ -164,7 +164,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/adt/include/adt/adt.h b/source/adt/include/adt/adt.h index e957f0fc96..040bd1fc50 100644 --- a/source/adt/include/adt/adt.h +++ b/source/adt/include/adt/adt.h @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/include/adt/adt_bucket.h b/source/adt/include/adt/adt_bucket.h index 52a536aa1c..4fb799f189 100644 --- a/source/adt/include/adt/adt_bucket.h +++ b/source/adt/include/adt/adt_bucket.h @@ -1,6 +1,6 @@ /* * Abstract Data Type Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A abstract data type library providing generic containers. * diff --git a/source/adt/include/adt/adt_comparable.h b/source/adt/include/adt/adt_comparable.h index d6ede66274..54fc2d2b84 100644 --- a/source/adt/include/adt/adt_comparable.h +++ b/source/adt/include/adt/adt_comparable.h @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/include/adt/adt_hash.h b/source/adt/include/adt/adt_hash.h index d2eefc6117..3601d4676c 100644 --- a/source/adt/include/adt/adt_hash.h +++ b/source/adt/include/adt/adt_hash.h @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/include/adt/adt_map.h b/source/adt/include/adt/adt_map.h index 351ce57fd8..2a256463ed 100644 --- a/source/adt/include/adt/adt_map.h +++ b/source/adt/include/adt/adt_map.h @@ -1,6 +1,6 @@ /* * Abstract Data Type Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A abstract data type library providing generic containers. * @@ -51,6 +51,15 @@ typedef int (*map_cb_iterate)(map, map_key, map_value, map_cb_iterate_args); typedef struct map_iterator_type *map_iterator; +/* -- Member Data -- */ + +struct map_iterator_type +{ + map m; + size_t current_bucket; + size_t current_pair; +}; + /* -- Methods -- */ ADT_API map map_create(map_cb_hash hash_cb, map_cb_compare compare_cb); @@ -79,15 +88,15 @@ ADT_API int map_clear(map m); ADT_API void map_destroy(map m); -ADT_API map_iterator map_iterator_begin(map m); +ADT_API void map_iterator_begin(map_iterator it, map m); -ADT_API map_key map_iterator_get_key(map_iterator it); +ADT_API map_key map_iterator_key(map_iterator it); -ADT_API map_value map_iterator_get_value(map_iterator it); +ADT_API map_value map_iterator_value(map_iterator it); ADT_API void map_iterator_next(map_iterator it); -ADT_API int map_iterator_end(map_iterator *it); +ADT_API int map_iterator_end(map_iterator it); #ifdef __cplusplus } diff --git a/source/adt/include/adt/adt_set.h b/source/adt/include/adt/adt_set.h index a69457d697..a662a90b8b 100644 --- a/source/adt/include/adt/adt_set.h +++ b/source/adt/include/adt/adt_set.h @@ -1,6 +1,6 @@ /* * Abstract Data Type Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A abstract data type library providing generic containers. * @@ -50,6 +50,15 @@ typedef int (*set_cb_iterate)(set, set_key, set_value, set_cb_iterate_args); typedef struct set_iterator_type *set_iterator; +/* -- Member Data -- */ + +struct set_iterator_type +{ + set s; + size_t current_bucket; + size_t current_pair; +}; + /* -- Methods -- */ ADT_API set set_create(set_cb_hash hash_cb, set_cb_compare compare_cb); @@ -80,15 +89,15 @@ ADT_API int set_clear(set s); ADT_API void set_destroy(set s); -ADT_API set_iterator set_iterator_begin(set s); +ADT_API void set_iterator_begin(set_iterator it, set s); -ADT_API set_key set_iterator_get_key(set_iterator it); +ADT_API set_key set_iterator_key(set_iterator it); -ADT_API set_value set_iterator_get_value(set_iterator it); +ADT_API set_value set_iterator_value(set_iterator it); ADT_API void set_iterator_next(set_iterator it); -ADT_API int set_iterator_end(set_iterator *it); +ADT_API int set_iterator_end(set_iterator it); #ifdef __cplusplus } diff --git a/source/adt/include/adt/adt_string.h b/source/adt/include/adt/adt_string.h index 3ef21e06b0..1b50369a8d 100644 --- a/source/adt/include/adt/adt_string.h +++ b/source/adt/include/adt/adt_string.h @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/include/adt/adt_trie.h b/source/adt/include/adt/adt_trie.h index f6eec21a99..899e1f9296 100644 --- a/source/adt/include/adt/adt_trie.h +++ b/source/adt/include/adt/adt_trie.h @@ -1,6 +1,6 @@ /* * Abstract Data Type Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A abstract data type library providing generic containers. * diff --git a/source/adt/include/adt/adt_vector.h b/source/adt/include/adt/adt_vector.h index 7cb7404b4a..d727171687 100644 --- a/source/adt/include/adt/adt_vector.h +++ b/source/adt/include/adt/adt_vector.h @@ -1,6 +1,6 @@ /* * Abstract Data Type Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A abstract data type library providing generic containers. * diff --git a/source/adt/source/adt.c b/source/adt/source/adt.c index 227fbb9c94..eeaf243223 100644 --- a/source/adt/source/adt.c +++ b/source/adt/source/adt.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ const char *adt_print_info(void) { static const char adt_info[] = "Abstract Data Type Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef ADT_STATIC_DEFINE "Compiled as static library type" diff --git a/source/adt/source/adt_bucket.c b/source/adt/source/adt_bucket.c index fa039301d0..98f7398751 100644 --- a/source/adt/source/adt_bucket.c +++ b/source/adt/source/adt_bucket.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/source/adt_comparable.c b/source/adt/source/adt_comparable.c index 0b7133621c..037be1f9be 100644 --- a/source/adt/source/adt_comparable.c +++ b/source/adt/source/adt_comparable.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/source/adt_hash.c b/source/adt/source/adt_hash.c index 766c68c477..2800af3b60 100644 --- a/source/adt/source/adt_hash.c +++ b/source/adt/source/adt_hash.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/adt/source/adt_map.c b/source/adt/source/adt_map.c index 75d5bcdaba..eb1768d0d9 100644 --- a/source/adt/source/adt_map.c +++ b/source/adt/source/adt_map.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,21 +42,6 @@ struct map_type map_cb_compare compare_cb; }; -struct map_iterator_type -{ - map m; - size_t current_bucket; - size_t current_pair; -}; - -struct map_contains_any_cb_iterator_type -{ - map m; - int result; -}; - -typedef struct map_contains_any_cb_iterator_type *map_contains_any_cb_iterator; - /* -- Methods -- */ map map_create(map_cb_hash hash_cb, map_cb_compare compare_cb) @@ -104,30 +89,38 @@ size_t map_size(map m) return 0; } -static int map_bucket_realloc_iterator(map m, map_key key, map_value value, map_cb_iterate_args args) +static int map_bucket_rehash(map m, map new_map) { - map new_map = (map)args; + size_t bucket_iterator, pair_iterator; - if (new_map != m && key != NULL && args != NULL) + for (bucket_iterator = 0; bucket_iterator < m->capacity; ++bucket_iterator) { - map_hash h = new_map->hash_cb(key); + bucket b = &m->buckets[bucket_iterator]; - size_t index = h % new_map->capacity; + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - bucket b = &new_map->buckets[index]; + map_hash h = new_map->hash_cb(p->key); - if (bucket_insert(b, key, value) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid map bucket realloc insertion"); - return 1; - } + size_t index = h % new_map->capacity; - ++new_map->count; + bucket new_bucket = &new_map->buckets[index]; - return 0; + if (bucket_insert(new_bucket, p->key, p->value) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid map bucket realloc insertion"); + return 1; + } + + ++new_map->count; + } + } } - return 1; + return 0; } static int map_bucket_realloc(map m) @@ -160,8 +153,10 @@ static int map_bucket_realloc(map m) { size_t iterator; - map_iterate(m, &map_bucket_realloc_iterator, &new_map); + /* Rehash all the elements into the new map */ + map_bucket_rehash(m, &new_map); + /* Destroy all pairs from old map */ for (iterator = 0; iterator < m->capacity; ++iterator) { bucket b = &m->buckets[iterator]; @@ -172,6 +167,7 @@ static int map_bucket_realloc(map m) } } + /* Destroy all buckets from old map */ free(m->buckets); m->capacity = new_map.capacity; @@ -239,9 +235,9 @@ vector map_get(map m, map_key key) { if (m != NULL && key != NULL) { - map_hash hash = m->hash_cb(key); + map_hash h = m->hash_cb(key); - size_t index = hash % m->capacity; + size_t index = h % m->capacity; bucket b = &m->buckets[index]; @@ -255,9 +251,9 @@ int map_contains(map m, map_key key) { if (m != NULL && key != NULL) { - map_hash hash = m->hash_cb(key); + map_hash h = m->hash_cb(key); - size_t index = hash % m->capacity; + size_t index = h % m->capacity; bucket b = &m->buckets[index]; @@ -272,29 +268,29 @@ int map_contains(map m, map_key key) return 1; } -static int map_contains_any_cb_iterate(map m, map_key key, map_value value, map_cb_iterate_args args) -{ - map_contains_any_cb_iterator iterator = (map_contains_any_cb_iterator)args; - - (void)m; - (void)value; - - iterator->result = map_contains(iterator->m, key); - - /* Stop iteration if we found an element */ - return !iterator->result; -} - int map_contains_any(map dest, map src) { - struct map_contains_any_cb_iterator_type args; + size_t bucket_iterator, pair_iterator; - args.m = dest; - args.result = 1; + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; - map_iterate(src, &map_contains_any_cb_iterate, (map_cb_iterate_args)&args); + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - return args.result; + if (map_contains(dest, p->key) == 0) + { + return 0; + } + } + } + } + + return 1; } map_value map_remove(map m, map_key key) @@ -413,20 +409,27 @@ void map_iterate(map m, map_cb_iterate iterate_cb, map_cb_iterate_args args) } } -static int map_append_cb_iterate(map m, map_key key, map_value value, map_cb_iterate_args args) +int map_append(map dest, map src) { - map dest = (map)args; - - (void)m; + size_t bucket_iterator, pair_iterator; - return map_insert(dest, key, value); -} + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; -int map_append(map dest, map src) -{ - map_cb_iterate_args args = (map_cb_iterate_args)dest; + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - map_iterate(src, &map_append_cb_iterate, args); + if (map_insert(dest, p->key, p->value) != 0) + { + return 1; + } + } + } + } return 0; } @@ -496,30 +499,29 @@ void map_destroy(map m) free(m); } -map_iterator map_iterator_begin(map m) +void map_iterator_begin(map_iterator it, map m) { - if (m != NULL && m->buckets != NULL && map_size(m) > 0) + if (it != NULL) { - map_iterator it = malloc(sizeof(struct map_iterator_type)); + it->current_bucket = 0; + it->current_pair = 0; - if (it != NULL) + if (m != NULL && m->buckets != NULL && map_size(m) > 0) { it->m = m; - it->current_bucket = 0; - it->current_pair = 0; map_iterator_next(it); - - return it; + } + else + { + it->m = NULL; } } - - return NULL; } -map_key map_iterator_get_key(map_iterator it) +map_key map_iterator_key(map_iterator it) { - if (it != NULL && it->current_bucket < it->m->capacity && it->current_pair > 0) + if (it != NULL && it->m != NULL && it->current_bucket < it->m->capacity && it->current_pair > 0) { return it->m->buckets[it->current_bucket].pairs[it->current_pair - 1].key; } @@ -527,9 +529,9 @@ map_key map_iterator_get_key(map_iterator it) return NULL; } -map_value map_iterator_get_value(map_iterator it) +map_value map_iterator_value(map_iterator it) { - if (it != NULL && it->current_bucket < it->m->capacity && it->current_pair > 0) + if (it != NULL && it->m != NULL && it->current_bucket < it->m->capacity && it->current_pair > 0) { return it->m->buckets[it->current_bucket].pairs[it->current_pair - 1].value; } @@ -539,7 +541,7 @@ map_value map_iterator_get_value(map_iterator it) void map_iterator_next(map_iterator it) { - if (it != NULL) + if (it != NULL && it->m != NULL) { for (; it->current_bucket < it->m->capacity; ++it->current_bucket) { @@ -559,20 +561,18 @@ void map_iterator_next(map_iterator it) } } } + + it->current_pair = 0; } } } -int map_iterator_end(map_iterator *it) +int map_iterator_end(map_iterator it) { - if (it != NULL && *it != NULL) + if (it != NULL && it->m != NULL) { - if ((*it)->current_bucket >= (*it)->m->capacity) + if (it->current_bucket >= it->m->capacity) { - free(*it); - - *it = NULL; - return 0; } diff --git a/source/adt/source/adt_set.c b/source/adt/source/adt_set.c index a25d6d8a0d..2ffd457172 100644 --- a/source/adt/source/adt_set.c +++ b/source/adt/source/adt_set.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,29 +42,6 @@ struct set_type set_cb_compare compare_cb; }; -struct set_iterator_type -{ - set s; - size_t current_bucket; - size_t current_pair; -}; - -struct set_contains_any_cb_iterator_type -{ - set s; - int result; -}; - -struct set_contains_which_cb_iterator_type -{ - set s; - int result; - set_key *key; -}; - -typedef struct set_contains_any_cb_iterator_type *set_contains_any_cb_iterator; -typedef struct set_contains_which_cb_iterator_type *set_contains_which_cb_iterator; - /* -- Methods -- */ set set_create(set_cb_hash hash_cb, set_cb_compare compare_cb) @@ -112,6 +89,8 @@ size_t set_size(set s) return 0; } +/* + static int set_bucket_realloc_iterator(set s, set_key key, set_value value, set_cb_iterate_args args) { set new_set = (set)args; @@ -137,6 +116,41 @@ static int set_bucket_realloc_iterator(set s, set_key key, set_value value, set_ return 1; } +*/ + +static int set_bucket_rehash(set s, set new_set) +{ + size_t bucket_iterator, pair_iterator; + + for (bucket_iterator = 0; bucket_iterator < s->capacity; ++bucket_iterator) + { + bucket b = &s->buckets[bucket_iterator]; + + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; + + set_hash h = new_set->hash_cb(p->key); + + size_t index = h % new_set->capacity; + + bucket new_bucket = &new_set->buckets[index]; + + if (bucket_insert(new_bucket, p->key, p->value) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid set bucket realloc insertion"); + return 1; + } + + ++new_set->count; + } + } + } + + return 0; +} static int set_bucket_realloc(set s) { @@ -168,8 +182,10 @@ static int set_bucket_realloc(set s) { size_t iterator; - set_iterate(s, &set_bucket_realloc_iterator, &new_set); + /* Rehash all the elements into the new set */ + set_bucket_rehash(s, &new_set); + /* Destroy all pairs from old set */ for (iterator = 0; iterator < s->capacity; ++iterator) { bucket b = &s->buckets[iterator]; @@ -180,6 +196,7 @@ static int set_bucket_realloc(set s) } } + /* Destroy all buckets from old set */ free(s->buckets); s->capacity = new_set.capacity; @@ -256,9 +273,9 @@ set_value set_get(set s, set_key key) { if (s != NULL && key != NULL) { - set_hash hash = s->hash_cb(key); + set_hash h = s->hash_cb(key); - size_t index = hash % s->capacity; + size_t index = h % s->capacity; bucket b = &s->buckets[index]; @@ -277,9 +294,9 @@ int set_contains(set s, set_key key) { if (s != NULL && key != NULL) { - set_hash hash = s->hash_cb(key); + set_hash h = s->hash_cb(key); - size_t index = hash % s->capacity; + size_t index = h % s->capacity; bucket b = &s->buckets[index]; @@ -294,63 +311,55 @@ int set_contains(set s, set_key key) return 1; } -static int set_contains_any_cb_iterate(set s, set_key key, set_value value, set_cb_iterate_args args) -{ - set_contains_any_cb_iterator iterator = (set_contains_any_cb_iterator)args; - - (void)s; - (void)value; - - iterator->result = set_contains(iterator->s, key); - - /* Stop iteration if we found an element */ - return !iterator->result; -} - int set_contains_any(set dest, set src) { - struct set_contains_any_cb_iterator_type args; - - args.s = dest; - args.result = 1; - - set_iterate(src, &set_contains_any_cb_iterate, (set_cb_iterate_args)&args); - - return args.result; -} - -static int set_contains_which_cb_iterate(set s, set_key key, set_value value, set_cb_iterate_args args) -{ - set_contains_which_cb_iterator iterator = (set_contains_which_cb_iterator)args; + size_t bucket_iterator, pair_iterator; - (void)s; - (void)value; + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; - iterator->result = set_contains(iterator->s, key); + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - if (iterator->result == 0) - { - iterator->key = key; + if (set_contains(dest, p->key) == 0) + { + return 0; + } + } + } } - /* Stop iteration if we found an element */ - return !iterator->result; + return 1; } int set_contains_which(set dest, set src, set_key *key) { - struct set_contains_which_cb_iterator_type args; + size_t bucket_iterator, pair_iterator; - args.s = dest; - args.result = 1; - args.key = NULL; + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; - set_iterate(src, &set_contains_which_cb_iterate, (set_cb_iterate_args)&args); + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - /* Return which is the duplicated key if any */ - *key = args.key; + if (set_contains(dest, p->key) == 0) + { + *key = p->key; + return 0; + } + } + } + } - return args.result; + return 1; } set_value set_remove(set s, set_key key) @@ -417,40 +426,54 @@ void set_iterate(set s, set_cb_iterate iterate_cb, set_cb_iterate_args args) } } -static int set_append_cb_iterate(set s, set_key key, set_value value, set_cb_iterate_args args) +int set_append(set dest, set src) { - set dest = (set)args; - - (void)s; + size_t bucket_iterator, pair_iterator; - return set_insert(dest, key, value); -} + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; -int set_append(set dest, set src) -{ - set_cb_iterate_args args = (set_cb_iterate_args)dest; + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; - set_iterate(src, &set_append_cb_iterate, args); + if (set_insert(dest, p->key, p->value) != 0) + { + return 1; + } + } + } + } return 0; } -static int set_disjoint_cb_iterate(set s, set_key key, set_value value, set_cb_iterate_args args) +int set_disjoint(set dest, set src) { - set dest = (set)args; - - set_value deleted = set_remove(dest, key); + size_t bucket_iterator, pair_iterator; - (void)s; + for (bucket_iterator = 0; bucket_iterator < src->capacity; ++bucket_iterator) + { + bucket b = &src->buckets[bucket_iterator]; - return !(deleted == value); -} + if (b->pairs != NULL && b->count > 0) + { + for (pair_iterator = 0; pair_iterator < b->count; ++pair_iterator) + { + pair p = &b->pairs[pair_iterator]; -int set_disjoint(set dest, set src) -{ - set_cb_iterate_args args = (set_cb_iterate_args)dest; + set_value deleted = set_remove(dest, p->key); - set_iterate(src, &set_disjoint_cb_iterate, args); + if (deleted != p->value) + { + return 1; + } + } + } + } return 0; } @@ -520,30 +543,29 @@ void set_destroy(set s) free(s); } -set_iterator set_iterator_begin(set s) +void set_iterator_begin(set_iterator it, set s) { - if (s != NULL && s->buckets != NULL && set_size(s) > 0) + if (it != NULL) { - set_iterator it = malloc(sizeof(struct set_iterator_type)); + it->current_bucket = 0; + it->current_pair = 0; - if (it != NULL) + if (s != NULL && s->buckets != NULL && set_size(s) > 0) { it->s = s; - it->current_bucket = 0; - it->current_pair = 0; set_iterator_next(it); - - return it; + } + else + { + it->s = NULL; } } - - return NULL; } -set_key set_iterator_get_key(set_iterator it) +set_key set_iterator_key(set_iterator it) { - if (it != NULL && it->current_bucket < it->s->capacity && it->current_pair > 0) + if (it != NULL && it->s != NULL && it->current_bucket < it->s->capacity && it->current_pair > 0) { return it->s->buckets[it->current_bucket].pairs[it->current_pair - 1].key; } @@ -551,9 +573,9 @@ set_key set_iterator_get_key(set_iterator it) return NULL; } -set_value set_iterator_get_value(set_iterator it) +set_value set_iterator_value(set_iterator it) { - if (it != NULL && it->current_bucket < it->s->capacity && it->current_pair > 0) + if (it != NULL && it->s != NULL && it->current_bucket < it->s->capacity && it->current_pair > 0) { return it->s->buckets[it->current_bucket].pairs[it->current_pair - 1].value; } @@ -563,7 +585,7 @@ set_value set_iterator_get_value(set_iterator it) void set_iterator_next(set_iterator it) { - if (it != NULL) + if (it != NULL && it->s != NULL) { for (; it->current_bucket < it->s->capacity; ++it->current_bucket) { @@ -582,21 +604,19 @@ void set_iterator_next(set_iterator it) return; } } + + it->current_pair = 0; } } } } -int set_iterator_end(set_iterator *it) +int set_iterator_end(set_iterator it) { - if (it != NULL && *it != NULL) + if (it != NULL && it->s != NULL) { - if ((*it)->current_bucket >= (*it)->s->capacity) + if (it->current_bucket >= it->s->capacity) { - free(*it); - - *it = NULL; - return 0; } diff --git a/source/adt/source/adt_trie.c b/source/adt/source/adt_trie.c index 71065b6ea4..047c20a698 100644 --- a/source/adt/source/adt_trie.c +++ b/source/adt/source/adt_trie.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -524,10 +524,11 @@ void trie_node_iterate(trie t, trie_node n, trie_cb_iterate iterate_cb, trie_cb_ if (back->childs != NULL) { - set_iterator it; - for (it = set_iterator_begin(back->childs); set_iterator_end(&it) > 0; set_iterator_next(it)) + struct set_iterator_type it; + + for (set_iterator_begin(&it, back->childs); set_iterator_end(&it) > 0; set_iterator_next(&it)) { - trie_node_ref ref_node = set_iterator_get_value(it); + trie_node_ref ref_node = set_iterator_value(&it); trie_node current_node = &t->node_list[ref_node->index]; @@ -609,11 +610,11 @@ int trie_node_clear(trie t, trie_node n) if (back->childs != NULL) { - set_iterator it; + struct set_iterator_type it; - for (it = set_iterator_begin(back->childs); set_iterator_end(&it) > 0; set_iterator_next(it)) + for (set_iterator_begin(&it, back->childs); set_iterator_end(&it) > 0; set_iterator_next(&it)) { - trie_node_ref ref_node = set_iterator_get_value(it); + trie_node_ref ref_node = set_iterator_value(&it); trie_node current_node = &t->node_list[ref_node->index]; @@ -681,14 +682,13 @@ trie_node trie_node_find(trie t, trie_key key) if (back_ptr != NULL && *back_ptr != NULL) { trie_node back = *back_ptr; - - set_iterator it = NULL; + struct set_iterator_type it; if (back->childs != NULL) { - for (it = set_iterator_begin(back->childs); set_iterator_end(&it) > 0; set_iterator_next(it)) + for (set_iterator_begin(&it, back->childs); set_iterator_end(&it) > 0; set_iterator_next(&it)) { - trie_node_ref ref_node = set_iterator_get_value(it); + trie_node_ref ref_node = set_iterator_value(&it); trie_node current_node = &t->node_list[ref_node->index]; @@ -698,9 +698,10 @@ trie_node trie_node_find(trie t, trie_key key) if (back->key != NULL && t->compare_cb(back->key, key) == 0) { + /* TODO: it may be un-initialized here */ while (set_iterator_end(&it) > 0) { - set_iterator_next(it); + set_iterator_next(&it); } vector_destroy(node_stack); diff --git a/source/adt/source/adt_vector.c b/source/adt/source/adt_vector.c index d4a725773e..0047cc1185 100644 --- a/source/adt/source/adt_vector.c +++ b/source/adt/source/adt_vector.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/benchmarks/CMakeLists.txt b/source/benchmarks/CMakeLists.txt index 8bf6ce15e8..107a348e81 100644 --- a/source/benchmarks/CMakeLists.txt +++ b/source/benchmarks/CMakeLists.txt @@ -58,6 +58,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/b include(CTest) +add_subdirectory(set_bench) add_subdirectory(log_bench) add_subdirectory(metacall_py_c_api_bench) add_subdirectory(metacall_py_call_bench) diff --git a/source/benchmarks/log_bench/CMakeLists.txt b/source/benchmarks/log_bench/CMakeLists.txt index 63f7c901e3..f1ba5575ea 100644 --- a/source/benchmarks/log_bench/CMakeLists.txt +++ b/source/benchmarks/log_bench/CMakeLists.txt @@ -108,7 +108,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/log_bench/source/log_bench.cpp b/source/benchmarks/log_bench/source/log_bench.cpp index 9ca700767d..75bdb547bd 100644 --- a/source/benchmarks/log_bench/source/log_bench.cpp +++ b/source/benchmarks/log_bench/source/log_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ #include #include -#include static int stream_write(void *, const char *, const size_t) { diff --git a/source/benchmarks/metacall_cs_call_bench/CMakeLists.txt b/source/benchmarks/metacall_cs_call_bench/CMakeLists.txt index 618c9a7eec..80db3ce393 100644 --- a/source/benchmarks/metacall_cs_call_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_cs_call_bench/CMakeLists.txt @@ -109,7 +109,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_cs_call_bench/source/metacall_cs_call_bench.cpp b/source/benchmarks/metacall_cs_call_bench/source/metacall_cs_call_bench.cpp index e16f199a8f..179dfaf6c0 100644 --- a/source/benchmarks/metacall_cs_call_bench/source/metacall_cs_call_bench.cpp +++ b/source/benchmarks/metacall_cs_call_bench/source/metacall_cs_call_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -186,5 +186,7 @@ int main(int argc, char **argv) ::benchmark::RunSpecifiedBenchmarks(); - return metacall_destroy(); + metacall_destroy(); + + return 0; } diff --git a/source/benchmarks/metacall_node_call_bench/CMakeLists.txt b/source/benchmarks/metacall_node_call_bench/CMakeLists.txt index 37aa304362..16ae8e7684 100644 --- a/source/benchmarks/metacall_node_call_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_node_call_bench/CMakeLists.txt @@ -109,7 +109,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_node_call_bench/source/metacall_node_call_bench.cpp b/source/benchmarks/metacall_node_call_bench/source/metacall_node_call_bench.cpp index f66efa2ab7..16d2c987b5 100644 --- a/source/benchmarks/metacall_node_call_bench/source/metacall_node_call_bench.cpp +++ b/source/benchmarks/metacall_node_call_bench/source/metacall_node_call_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -292,5 +292,7 @@ int main(int argc, char **argv) } #endif /* OPTION_BUILD_LOADERS_NODE */ - return metacall_destroy(); + metacall_destroy(); + + return 0; } diff --git a/source/benchmarks/metacall_py_c_api_bench/CMakeLists.txt b/source/benchmarks/metacall_py_c_api_bench/CMakeLists.txt index 1807f755af..08605fb08d 100644 --- a/source/benchmarks/metacall_py_c_api_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_py_c_api_bench/CMakeLists.txt @@ -121,7 +121,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_py_c_api_bench/source/metacall_py_c_api_bench.cpp b/source/benchmarks/metacall_py_c_api_bench/source/metacall_py_c_api_bench.cpp index de8f43d8bc..e1db6bb14b 100644 --- a/source/benchmarks/metacall_py_c_api_bench/source/metacall_py_c_api_bench.cpp +++ b/source/benchmarks/metacall_py_c_api_bench/source/metacall_py_c_api_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/benchmarks/metacall_py_call_bench/CMakeLists.txt b/source/benchmarks/metacall_py_call_bench/CMakeLists.txt index 898bddd699..9ed6744229 100644 --- a/source/benchmarks/metacall_py_call_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_py_call_bench/CMakeLists.txt @@ -109,7 +109,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_py_call_bench/source/metacall_py_call_bench.cpp b/source/benchmarks/metacall_py_call_bench/source/metacall_py_call_bench.cpp index 399ebe2396..68b0bf5890 100644 --- a/source/benchmarks/metacall_py_call_bench/source/metacall_py_call_bench.cpp +++ b/source/benchmarks/metacall_py_call_bench/source/metacall_py_call_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,10 +178,7 @@ int main(int argc, char *argv[]) ::benchmark::RunSpecifiedBenchmarks(); ::benchmark::Shutdown(); - if (metacall_destroy() != 0) - { - return 4; - } + metacall_destroy(); return 0; } diff --git a/source/benchmarks/metacall_py_init_bench/CMakeLists.txt b/source/benchmarks/metacall_py_init_bench/CMakeLists.txt index 9933482d18..eb9ecb2c79 100644 --- a/source/benchmarks/metacall_py_init_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_py_init_bench/CMakeLists.txt @@ -109,7 +109,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_py_init_bench/source/metacall_py_init_bench.cpp b/source/benchmarks/metacall_py_init_bench/source/metacall_py_init_bench.cpp index 7021aad6b5..9a1ef4a886 100644 --- a/source/benchmarks/metacall_py_init_bench/source/metacall_py_init_bench.cpp +++ b/source/benchmarks/metacall_py_init_bench/source/metacall_py_init_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,10 +130,7 @@ BENCHMARK_DEFINE_F(metacall_py_init_bench, destroy) /* Python */ #if defined(OPTION_BUILD_LOADERS_PY) { - if (metacall_destroy() != 0) - { - state.SkipWithError("Error destroying MetaCall"); - } + metacall_destroy(); } #endif /* OPTION_BUILD_LOADERS_PY */ } diff --git a/source/benchmarks/metacall_rb_call_bench/CMakeLists.txt b/source/benchmarks/metacall_rb_call_bench/CMakeLists.txt index 5643afe0b7..4833bad0de 100644 --- a/source/benchmarks/metacall_rb_call_bench/CMakeLists.txt +++ b/source/benchmarks/metacall_rb_call_bench/CMakeLists.txt @@ -109,7 +109,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/benchmarks/metacall_rb_call_bench/source/metacall_rb_call_bench.cpp b/source/benchmarks/metacall_rb_call_bench/source/metacall_rb_call_bench.cpp index ddcfd27956..4dc75e9424 100644 --- a/source/benchmarks/metacall_rb_call_bench/source/metacall_rb_call_bench.cpp +++ b/source/benchmarks/metacall_rb_call_bench/source/metacall_rb_call_bench.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,10 +198,7 @@ int main(int argc, char *argv[]) ::benchmark::RunSpecifiedBenchmarks(); ::benchmark::Shutdown(); - if (metacall_destroy() != 0) - { - return 4; - } + metacall_destroy(); return 0; } diff --git a/source/benchmarks/set_bench/CMakeLists.txt b/source/benchmarks/set_bench/CMakeLists.txt new file mode 100644 index 0000000000..69630fada5 --- /dev/null +++ b/source/benchmarks/set_bench/CMakeLists.txt @@ -0,0 +1,147 @@ +# +# Executable name and options +# + +# Target name +set(target set-bench) +message(STATUS "Benchmark ${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}/set_bench.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} + + GBench + + ${META_PROJECT_NAME}::version + ${META_PROJECT_NAME}::preprocessor + ${META_PROJECT_NAME}::format + ${META_PROJECT_NAME}::threading + ${META_PROJECT_NAME}::log + ${META_PROJECT_NAME}::adt +) + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + ${DEFAULT_COMPILE_DEFINITIONS} +) + +# +# Compile options +# + +target_compile_options(${target} + PRIVATE + ${DEFAULT_COMPILE_OPTIONS} +) + +# +# Linker options +# + +target_link_options(${target} + PRIVATE + ${DEFAULT_LINKER_OPTIONS} +) + +# +# Define test +# + +add_test(NAME ${target} + COMMAND $ + --benchmark_out=${CMAKE_BINARY_DIR}/benchmarks/${target}.json +) + +# +# Define dependencies +# + +add_dependencies(${target} + adt +) + +# +# Define test properties +# + +set_property(TEST ${target} + PROPERTY LABELS ${target} +) + +include(TestEnvironmentVariables) + +test_environment_variables(${target} + "" + ${TESTS_ENVIRONMENT_VARIABLES} +) diff --git a/source/benchmarks/set_bench/source/set_bench.cpp b/source/benchmarks/set_bench/source/set_bench.cpp new file mode 100644 index 0000000000..2129c98b54 --- /dev/null +++ b/source/benchmarks/set_bench/source/set_bench.cpp @@ -0,0 +1,147 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 + +#include + +#include +#include + +#define SET_SIZE 1000 +#define ITERATIONS 1000 + +class set_bench : public benchmark::Fixture +{ +public: + void SetUp(benchmark::State &) + { + s = set_create(&hash_callback_ptr, &comparable_callback_ptr); + + keys.reserve(SET_SIZE); + values.reserve(SET_SIZE); + + for (int i = 0; i < SET_SIZE; ++i) + { + keys.push_back(std::to_string(i)); + values.push_back(i); + set_insert(s, (set_key)keys[i].c_str(), &values[i]); + } + } + + void TearDown(benchmark::State &) + { + set_destroy(s); + } + + set s; + std::vector keys; + std::vector values; +}; + +int set_cb_iterate_sum(set s, set_key key, set_value value, set_cb_iterate_args args) +{ + int *i = (int *)value; + uint64_t *sum = (uint64_t *)args; + + (void)s; + (void)key; + + *sum = ((*sum) + (uint64_t)(*i)); + + return 0; +} + +BENCHMARK_DEFINE_F(set_bench, set_iterate) +(benchmark::State &state) +{ + uint64_t sum = 0; + + for (auto _ : state) + { + set_iterate(s, &set_cb_iterate_sum, &sum); + } + + state.SetLabel("Set Benchmark - Iterate Callback"); + state.SetItemsProcessed(SET_SIZE); +} + +BENCHMARK_REGISTER_F(set_bench, set_iterate) + ->Unit(benchmark::kMillisecond) + ->Iterations(ITERATIONS) + ->Repetitions(3); + +/* +BENCHMARK_DEFINE_F(set_bench, set_iterators) +(benchmark::State &state) +{ + uint64_t sum = 0; + + for (auto _ : state) + { + for (set_iterator it = set_iterator_begin(s); set_iterator_end(&it) > 0; set_iterator_next(it)) + { + int *i = (int *)set_iterator_value(it); + + sum += ((uint64_t)(*i)); + } + } + + (void)sum; + + state.SetLabel("Set Benchmark - Iterators"); + state.SetItemsProcessed(SET_SIZE); +} + +BENCHMARK_REGISTER_F(set_bench, set_iterators) + ->Unit(benchmark::kMillisecond) + ->Iterations(ITERATIONS) + ->Repetitions(3); +*/ + +BENCHMARK_DEFINE_F(set_bench, set_iterators_2) +(benchmark::State &state) +{ + uint64_t sum = 0; + + for (auto _ : state) + { + set_iterator_type it; + + for (set_iterator_begin(&it, s); set_iterator_end(&it) > 0; set_iterator_next(&it)) + { + int *i = (int *)set_iterator_value(&it); + + sum += ((uint64_t)(*i)); + } + } + + (void)sum; + + state.SetLabel("Set Benchmark - Iterators 2"); + state.SetItemsProcessed(SET_SIZE); +} + +BENCHMARK_REGISTER_F(set_bench, set_iterators_2) + ->Unit(benchmark::kMillisecond) + ->Iterations(ITERATIONS) + ->Repetitions(3); + +BENCHMARK_MAIN(); diff --git a/source/cli/metacallcli/CMakeLists.txt b/source/cli/metacallcli/CMakeLists.txt index fe6679dc3e..8067b8e620 100644 --- a/source/cli/metacallcli/CMakeLists.txt +++ b/source/cli/metacallcli/CMakeLists.txt @@ -139,7 +139,7 @@ target_compile_features(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -416,6 +416,21 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY) ) endif() +if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_RB) + add_test(NAME ${target}-rb-simplest + COMMAND $ simplest.rb + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + set_tests_properties(${target}-rb-simplest PROPERTIES + LABELS ${target}-rb-simplest + PASS_REGULAR_EXPRESSION "Hello from Ruby" + ) + test_environment_variables(${target}-rb-simplest + "" + ${TESTS_ENVIRONMENT_VARIABLES} + ) +endif() + if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND OPTION_BUILD_SCRIPTS_TS) add_test(NAME ${target}-ts COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$" -D "INPUT=${TEST_COMMAND_INPUT}-ts.txt" -P ${TEST_COMMAND_RUNNER} diff --git a/source/cli/metacallcli/include/metacallcli/application.hpp b/source/cli/metacallcli/include/metacallcli/application.hpp index 0fc2f788d4..c2e7863a8e 100644 --- a/source/cli/metacallcli/include/metacallcli/application.hpp +++ b/source/cli/metacallcli/include/metacallcli/application.hpp @@ -1,6 +1,6 @@ /* * MetaCall Command Line Interface by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A command line interface example as metacall wrapper. * diff --git a/source/cli/metacallcli/source/application.cpp b/source/cli/metacallcli/source/application.cpp index b1b22761b7..098f639006 100644 --- a/source/cli/metacallcli/source/application.cpp +++ b/source/cli/metacallcli/source/application.cpp @@ -1,6 +1,6 @@ /* * MetaCall Command Line Interface by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A command line interface example as metacall wrapper. * @@ -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 { @@ -134,14 +135,19 @@ bool application::cmd(std::vector &arguments) /* Initialize CMD descriptors */ std::string plugin_path(metacall_plugin_path()); - void *args[] = { + void *command_initialize_args[] = { metacall_value_create_string(plugin_path.c_str(), plugin_path.length()) }; - void *command_initialize_ret = metacallhv_s(plugin_cli_handle, "command_initialize", args, sizeof(args) / sizeof(args[0])); + void *command_initialize_ret = metacallhv_s(plugin_cli_handle, "command_initialize", command_initialize_args, sizeof(command_initialize_args) / sizeof(command_initialize_args[0])); check_for_exception(command_initialize_ret); + for (void *arg : command_initialize_args) + { + metacall_value_destroy(arg); + } + /* Convert all arguments into metacall value strings */ std::vector arguments_values; arguments_values.reserve(arguments.size()); @@ -179,11 +185,11 @@ bool application::cmd(std::vector &arguments) { void **command_pair = metacall_value_to_array(command_map[iterator]); - void *args[] = { + void *command_args[] = { command_pair[0] }; - void *command_func = metacallfv_s(command_function_func, args, sizeof(args) / sizeof(args[0])); + void *command_func = metacallfv_s(command_function_func, command_args, sizeof(command_args) / sizeof(command_args[0])); if (metacall_value_id(command_func) == METACALL_FUNCTION) { @@ -263,7 +269,7 @@ application::application(int argc, char *argv[]) : if (metacall_initialize() != 0) { /* Exit from application */ - return; + exit(1); } /* Initialize MetaCall arguments */ @@ -299,12 +305,7 @@ application::application(int argc, char *argv[]) : application::~application() { - int result = metacall_destroy(); - - if (result != 0) - { - std::cout << "Error while destroying MetaCall, exit code: " << result << std::endl; - } + metacall_destroy(); } void application::arguments_parse(std::vector &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); } } } diff --git a/source/cli/metacallcli/source/main.cpp b/source/cli/metacallcli/source/main.cpp index 1821d04b5e..8c41f19157 100644 --- a/source/cli/metacallcli/source/main.cpp +++ b/source/cli/metacallcli/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Command Line Interface by Parra Studios * A command line interface example as metacall wrapper. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/cli/plugins/cli_cmd_plugin/include/cli_cmd_plugin/cli_cmd_plugin.hpp b/source/cli/plugins/cli_cmd_plugin/include/cli_cmd_plugin/cli_cmd_plugin.hpp index 9565754caa..3a82b78469 100644 --- a/source/cli/plugins/cli_cmd_plugin/include/cli_cmd_plugin/cli_cmd_plugin.hpp +++ b/source/cli/plugins/cli_cmd_plugin/include/cli_cmd_plugin/cli_cmd_plugin.hpp @@ -2,7 +2,7 @@ * CLI Command Plugin by Parra Studios * A plugin implementing command line functionality for MetaCall CLI. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/cli/plugins/cli_core_plugin/CMakeLists.txt b/source/cli/plugins/cli_core_plugin/CMakeLists.txt index 2dd38f06de..680417f11c 100644 --- a/source/cli/plugins/cli_core_plugin/CMakeLists.txt +++ b/source/cli/plugins/cli_core_plugin/CMakeLists.txt @@ -180,7 +180,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h b/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h index e27865d260..5f43a1358d 100644 --- a/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h +++ b/source/cli/plugins/cli_core_plugin/include/cli_core_plugin/cli_core_plugin.h @@ -2,7 +2,7 @@ * CLI Core Plugin by Parra Studios * A plugin implementing core functionality for MetaCall CLI. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CLI_CORE_PLUGIN_API int cli_core_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(cli_core_plugin); - #ifdef __cplusplus } #endif diff --git a/source/cli/plugins/cli_core_plugin/source/cli_core_plugin.cpp b/source/cli/plugins/cli_core_plugin/source/cli_core_plugin.cpp index 5563fc4266..ea19c681d4 100644 --- a/source/cli/plugins/cli_core_plugin/source/cli_core_plugin.cpp +++ b/source/cli/plugins/cli_core_plugin/source/cli_core_plugin.cpp @@ -2,7 +2,7 @@ * CLI Core Plugin by Parra Studios * A plugin implementing core functionality for MetaCall CLI. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +49,7 @@ std::cout << "MetaCall Command Line Interface by Parra Studios" << std::endl; \ std::cout << "A command line interface for MetaCall Core" << std::endl; \ std::cout << std::endl; \ - std::cout << "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia " << std::endl; \ + std::cout << "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia " << std::endl; \ } while (0) template diff --git a/source/cli/plugins/cli_sandbox_plugin/CMakeLists.txt b/source/cli/plugins/cli_sandbox_plugin/CMakeLists.txt index e4d16acd2f..de380e948c 100644 --- a/source/cli/plugins/cli_sandbox_plugin/CMakeLists.txt +++ b/source/cli/plugins/cli_sandbox_plugin/CMakeLists.txt @@ -175,7 +175,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h b/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h index f0f1aa6711..f731ac1c0e 100644 --- a/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h +++ b/source/cli/plugins/cli_sandbox_plugin/include/cli_sandbox_plugin/cli_sandbox_plugin.h @@ -2,7 +2,7 @@ * CLI Sandbox Plugin by Parra Studios * A plugin implementing sandboxing functionality for MetaCall CLI. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CLI_SANDBOX_PLUGIN_API int cli_sandbox_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(cli_sandbox_plugin); - #ifdef __cplusplus } #endif diff --git a/source/cli/plugins/cli_sandbox_plugin/source/cli_sandbox_plugin.cpp b/source/cli/plugins/cli_sandbox_plugin/source/cli_sandbox_plugin.cpp index f7a78b130c..8a5390fab5 100644 --- a/source/cli/plugins/cli_sandbox_plugin/source/cli_sandbox_plugin.cpp +++ b/source/cli/plugins/cli_sandbox_plugin/source/cli_sandbox_plugin.cpp @@ -2,7 +2,7 @@ * CLI Sandbox Plugin by Parra Studios * A plugin implementing sandboxing functionality for MetaCall CLI. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/configuration/CMakeLists.txt b/source/configuration/CMakeLists.txt index c38ca6feb5..18b30a7ebc 100644 --- a/source/configuration/CMakeLists.txt +++ b/source/configuration/CMakeLists.txt @@ -164,7 +164,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC @@ -180,17 +180,28 @@ target_link_libraries(${target} function(configurations_write config_dir config_path) set(CONFIGURATION_GLOBAL "{") - if(OPTION_BUILD_LOADERS) - set(CONFIGURATION_GLOBAL_LOADERS 0) + # TODO: Make this automatic for all loaders + if(OPTION_BUILD_LOADERS) if(OPTION_BUILD_LOADERS_CS) set(CONFIGURATION_GLOBAL "${CONFIGURATION_GLOBAL}\n\t\"cs_loader\":\"${config_dir}/cs_loader.json\",") - set(CONFIGURATION_GLOBAL_LOADERS 1) + endif() + + if(OPTION_BUILD_LOADERS_NODE) + set(CONFIGURATION_GLOBAL "${CONFIGURATION_GLOBAL}\n\t\"node_loader\":\"${config_dir}/node_loader.json\",") + endif() + + if(OPTION_BUILD_LOADERS_PY) + set(CONFIGURATION_GLOBAL "${CONFIGURATION_GLOBAL}\n\t\"py_loader\":\"${config_dir}/py_loader.json\",") + endif() + + + if(OPTION_BUILD_LOADERS_RB) + set(CONFIGURATION_GLOBAL "${CONFIGURATION_GLOBAL}\n\t\"rb_loader\":\"${config_dir}/rb_loader.json\",") endif() #if(OPTION_BUILD_LOADERS_JS) # set(CONFIGURATION_GLOBAL "${CONFIGURATION_GLOBAL}\n\t\"js_loader\":\"${config_dir}/js_loader.json\",") - # set(CONFIGURATION_GLOBAL_LOADERS 1) #endif() endif() diff --git a/source/configuration/include/configuration/configuration.h b/source/configuration/include/configuration/configuration.h index 9182d8a090..3fa7811fad 100644 --- a/source/configuration/include/configuration/configuration.h +++ b/source/configuration/include/configuration/configuration.h @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * diff --git a/source/configuration/include/configuration/configuration_impl.h b/source/configuration/include/configuration/configuration_impl.h index bac8d2e89f..7c733b762b 100644 --- a/source/configuration/include/configuration/configuration_impl.h +++ b/source/configuration/include/configuration/configuration_impl.h @@ -2,7 +2,7 @@ * Configuration Library by Parra Studios * A cross-platform library for managing multiple configuration formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/configuration/include/configuration/configuration_object.h b/source/configuration/include/configuration/configuration_object.h index d98e920dd2..7a5f88679f 100644 --- a/source/configuration/include/configuration/configuration_object.h +++ b/source/configuration/include/configuration/configuration_object.h @@ -2,7 +2,7 @@ * Configuration Library by Parra Studios * A cross-platform library for managing multiple configuration formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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/include/configuration/configuration_object_handle.h b/source/configuration/include/configuration/configuration_object_handle.h index 73bfc7f04e..67b5011b92 100644 --- a/source/configuration/include/configuration/configuration_object_handle.h +++ b/source/configuration/include/configuration/configuration_object_handle.h @@ -2,7 +2,7 @@ * Configuration Library by Parra Studios * A cross-platform library for managing multiple configuration formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/configuration/include/configuration/configuration_singleton.h b/source/configuration/include/configuration/configuration_singleton.h index 44b1e52d12..5dbc6fa833 100644 --- a/source/configuration/include/configuration/configuration_singleton.h +++ b/source/configuration/include/configuration/configuration_singleton.h @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * diff --git a/source/configuration/source/configuration.c b/source/configuration/source/configuration.c index 0d287e7b37..e72793a192 100644 --- a/source/configuration/source/configuration.c +++ b/source/configuration/source/configuration.c @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * @@ -28,6 +28,37 @@ /* -- Methods -- */ +static int configuration_path_from_library_path(dynlink_path library_relative_path, const char relative_path[], size_t relative_path_size) +{ + static const char library_name[] = "metacall" +#if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) + "d" +#endif + ; + + dynlink_path library_path, join_path; + + size_t size, length = 0; + + if (dynlink_library_path(library_name, library_path, &length) != 0) + { + 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); + + /* Append the relative path */ + size = portability_path_join(library_path, size, relative_path, relative_path_size, join_path, PORTABILITY_PATH_SIZE); + + /* Make it cannonical */ + size = portability_path_canonical(join_path, size, library_relative_path, PORTABILITY_PATH_SIZE); + + return size == 0; +} + int configuration_initialize(const char *reader, const char *path, void *allocator) { configuration global = NULL; @@ -39,12 +70,20 @@ int configuration_initialize(const char *reader, const char *path, void *allocat return 1; } + /* The order of precedence is: + * 1) Environment variable + * 2) Default relative path to metacall library + * 3) Locate it relative to metacall library install path + * 4) Default installation path (if any) + */ if (path == NULL) { static const char configuration_path[] = CONFIGURATION_PATH; const char *env_path = environment_variable_get(configuration_path, NULL); + dynlink_path library_relative_path; + if (env_path != NULL) { global = configuration_object_initialize(CONFIGURATION_GLOBAL_SCOPE, env_path, NULL); @@ -56,9 +95,39 @@ int configuration_initialize(const char *reader, const char *path, void *allocat { static const char configuration_default_path[] = CONFIGURATION_DEFAULT_PATH; - global = configuration_object_initialize(CONFIGURATION_GLOBAL_SCOPE, configuration_default_path, NULL); + if (configuration_path_from_library_path(library_relative_path, configuration_default_path, sizeof(configuration_default_path)) == 0) + { + global = configuration_object_initialize(CONFIGURATION_GLOBAL_SCOPE, library_relative_path, NULL); + + path = library_relative_path; + } + } + +#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) + /* 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; + + 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; + + if (configuration_path_from_library_path(library_relative_path, relative_path, sizeof(relative_path)) == 0) + { + global = configuration_object_initialize(CONFIGURATION_GLOBAL_SCOPE, library_relative_path, NULL); - path = configuration_default_path; + path = library_relative_path; + } } #if defined(CONFIGURATION_INSTALL_PATH) @@ -254,7 +323,7 @@ const char *configuration_print_info(void) { static const char configuration_info[] = "Configuration Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef CONFIGURATION_STATIC_DEFINE "Compiled as static library type" diff --git a/source/configuration/source/configuration_impl.c b/source/configuration/source/configuration_impl.c index 137645119e..5482f73756 100644 --- a/source/configuration/source/configuration_impl.c +++ b/source/configuration/source/configuration_impl.c @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * @@ -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 f7044c97b7..8d5ec45848 100644 --- a/source/configuration/source/configuration_object.c +++ b/source/configuration/source/configuration_object.c @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * @@ -13,26 +13,12 @@ #include -#include - -/* -- Forward Declarations -- */ - -struct configuration_childs_cb_iterator_type; +#include -/* -- Type Definitions -- */ - -typedef struct configuration_childs_cb_iterator_type *configuration_childs_cb_iterator; +#include /* -- Member Data -- */ -struct configuration_childs_cb_iterator_type -{ - int result; - configuration parent; - vector childs; - set storage; -}; - struct configuration_type { char *name; @@ -45,28 +31,10 @@ struct configuration_type /* -- Private Methods -- */ -static int configuration_object_initialize_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - static char *configuration_object_read(const char *path); -static int configuration_object_childs_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - /* -- Methods -- */ -int configuration_object_initialize_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - set map = args; - - (void)s; - - if (key != NULL && val != NULL) - { - return set_insert(map, key, val); - } - - return 0; -} - char *configuration_object_read(const char *path) { FILE *file = fopen(path, "rb"); @@ -130,6 +98,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) @@ -190,7 +160,12 @@ configuration configuration_object_initialize(const char *name, const char *path if (config->parent != NULL) { - set_iterate(config->parent->map, &configuration_object_initialize_cb_iterate, config->map); + struct set_iterator_type it; + + for (set_iterator_begin(&it, config->parent->map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + set_insert(config->map, set_iterator_key(&it), set_iterator_value(&it)); + } } config->v = NULL; @@ -198,7 +173,7 @@ configuration configuration_object_initialize(const char *name, const char *path return config; } -int configuration_object_childs_cb_iterate_valid(set_key key, set_value val) +int configuration_object_childs_valid(set_key key, set_value val) { value v = val; @@ -243,48 +218,65 @@ int configuration_object_childs_cb_iterate_valid(set_key key, set_value val) return 1; } -int configuration_object_childs_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) +size_t configuration_object_child_path(configuration config, value v, char *path) { - (void)s; + const char *value_path = value_to_string(v); + size_t size = value_type_size(v); - if (configuration_object_childs_cb_iterate_valid(key, val) == 0) + if (portability_path_is_absolute(value_path, size) == 0) { - configuration_childs_cb_iterator iterator = args; - - if (set_get(iterator->storage, key) == NULL) - { - value v = val; - - const char *path = value_to_string(v); + memcpy(path, value_path, size); + } + else + { + char absolute_path[PORTABILITY_PATH_SIZE]; - configuration child = configuration_object_initialize(key, path, iterator->parent); + size_t absolute_path_size = portability_path_get_directory(config->path, strnlen(config->path, PORTABILITY_PATH_SIZE), absolute_path, PORTABILITY_PATH_SIZE); - if (child == NULL) - { - iterator->result = 1; + char join_path[PORTABILITY_PATH_SIZE]; - return 1; - } + size_t join_path_size = portability_path_join(absolute_path, absolute_path_size, value_path, size, join_path, PORTABILITY_PATH_SIZE); - vector_push_back(iterator->childs, &child); - } + size = portability_path_canonical(join_path, join_path_size, path, PORTABILITY_PATH_SIZE); } - return 0; + return size; } int configuration_object_childs(configuration config, vector childs, set storage) { - struct configuration_childs_cb_iterator_type iterator; + struct set_iterator_type it; + + for (set_iterator_begin(&it, config->map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + set_key key = set_iterator_key(&it); + set_value val = set_iterator_value(&it); + + if (configuration_object_childs_valid(key, val) == 0) + { + if (set_get(storage, key) == NULL) + { + char path[PORTABILITY_PATH_SIZE]; + + configuration child; + + configuration_object_child_path(config, val, path); - iterator.result = 0; - iterator.parent = config; - iterator.childs = childs; - iterator.storage = storage; + child = configuration_object_initialize(key, path, config); - set_iterate(config->map, &configuration_object_childs_cb_iterate, &iterator); + if (child == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load configuration %s from %s", (char *)key, path); - return iterator.result; + return 1; + } + + vector_push_back(childs, &child); + } + } + } + + return 0; } void configuration_object_instantiate(configuration config, value v) diff --git a/source/configuration/source/configuration_singleton.c b/source/configuration/source/configuration_singleton.c index 5b31812677..7d8d094b4c 100644 --- a/source/configuration/source/configuration_singleton.c +++ b/source/configuration/source/configuration_singleton.c @@ -1,6 +1,6 @@ /* * Configuration Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing multiple configuration formats. * @@ -25,10 +25,6 @@ struct configuration_singleton_type configuration global; }; -/* -- Private Methods -- */ - -static int configuration_singleton_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - /* -- Member Data -- */ static struct configuration_singleton_type configuration_singleton_default = { @@ -115,22 +111,6 @@ int configuration_singleton_clear(configuration config) return 0; } -int configuration_singleton_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - (void)args; - - if (val != NULL) - { - configuration config = val; - - configuration_object_destroy(config); - } - - return 0; -} - void configuration_singleton_destroy(void) { configuration_singleton singleton = configuration_singleton_instance(); @@ -139,7 +119,14 @@ void configuration_singleton_destroy(void) if (singleton->scopes != NULL) { - set_iterate(singleton->scopes, &configuration_singleton_destroy_cb_iterate, NULL); + struct set_iterator_type it; + + for (set_iterator_begin(&it, singleton->scopes); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + configuration config = set_iterator_value(&it); + + configuration_object_destroy(config); + } set_destroy(singleton->scopes); diff --git a/source/detour/CMakeLists.txt b/source/detour/CMakeLists.txt index 0a8a4e5d74..19e3a69195 100644 --- a/source/detour/CMakeLists.txt +++ b/source/detour/CMakeLists.txt @@ -157,7 +157,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/detour/include/detour/detour.h b/source/detour/include/detour/detour.h index d061bf19bd..9eb8d50fc6 100644 --- a/source/detour/include/detour/detour.h +++ b/source/detour/include/detour/detour.h @@ -1,6 +1,6 @@ /* * Detour Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library providing detours, function hooks and trampolines. * @@ -40,7 +40,7 @@ DETOUR_API int detour_initialize(void); * Create detour by @name * * @param[in] name -* Plugin will be used to detourize and detourize +* Plugin will be used for hooking * * @return * Pointer to detour on correct initialization, null otherwise @@ -63,35 +63,77 @@ DETOUR_API const char *detour_name(detour d); /** * @brief -* Get trampoline of the detour +* Initialize the detour of a library from @path * -* @param[in] handle -* Reference to the detour handle +* @param[in] d +* Reference to the detour +* +* @param[in] path +* String to the path or name of the library, in case of NULL, the current process will be used * * @return -* Pointer to the trampoline function +* Pointer to the detour handle * */ -DETOUR_API void (*detour_trampoline(detour_handle handle))(void); +DETOUR_API detour_handle detour_load_file(detour d, const char *path); /** * @brief -* Install detour from @target to @hook +* Initialize the detour of a library from @library dynlink handle * * @param[in] d * Reference to the detour * -* @param[in] target -* Reference to the function to be hooked +* @param[in] library +* Pointer to the library already opened by dynlink +* +* @return +* Pointer to the detour handle +* +*/ +DETOUR_API detour_handle detour_load_handle(detour d, dynlink library); + +/** +* @brief +* Initialize the detour of a library from @address, this function pointer +* must be a pointer to a function of the library that we want to hook +* +* @param[in] d +* Reference to the detour * -* @param[in] hook -* Reference to the function will be called instead of @target +* @param[in] address +* Pointer to a function of the library we want to hook * * @return * Pointer to the detour handle * */ -DETOUR_API detour_handle detour_install(detour d, void (*target)(void), void (*hook)(void)); +DETOUR_API detour_handle detour_load_address(detour d, void (*address)(void)); + +/** +* @brief +* Iterate all symbols of the library already opened +* +* @param[in] d +* Reference to the detour +* +* @param[in] handle +* Pointer to the detour hook implementation +* +* @param[out] position +* Pointer to the current index of the enumeration +* +* @param[out] name +* Pointer to the function name in string form +* +* @param[out] address +* Pointer to the pointer of the function pointer of the function to be hooked +* +* @return +* Return zero on success, different from zero otherwise +* +*/ +DETOUR_API int detour_enumerate(detour d, detour_handle handle, unsigned int *position, const char **name, void (***address)(void)); /** * @brief @@ -103,11 +145,33 @@ DETOUR_API detour_handle detour_install(detour d, void (*target)(void), void (*h * @param[in] handle * Reference to the detour handle * +* @param[in] function_name +* Function name to be hooked, it must belong to the library +* +* @param[in] function_addr +* Function pointer to the function that will replace the original function from the library +* +* @param[out] function_trampoline +* Function pointer to the original function from the library that will be replaced +* * @return * Return zero if success, different from zero otherwise * */ -DETOUR_API int detour_uninstall(detour d, detour_handle handle); +DETOUR_API int detour_replace(detour d, detour_handle handle, const char *function_name, void (*function_addr)(void), void (**function_trampoline)(void)); + +/** +* @brief +* Destroy detour handle previously loaded by detour_load_* functions +* +* @param[in] d +* Reference to the detour +* +* @param[in] handle +* Reference to the detour handle +* +*/ +DETOUR_API void detour_unload(detour d, detour_handle handle); /** * @brief diff --git a/source/detour/include/detour/detour_handle.h b/source/detour/include/detour/detour_handle.h index 7e9dde1b8e..28f21848d7 100644 --- a/source/detour/include/detour/detour_handle.h +++ b/source/detour/include/detour/detour_handle.h @@ -2,7 +2,7 @@ * Detour Library by Parra Studios * A cross-platform library providing detours, function hooks and trampolines. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/detour/include/detour/detour_interface.h b/source/detour/include/detour/detour_interface.h index 425ba151d7..d4ac5b5e81 100644 --- a/source/detour/include/detour/detour_interface.h +++ b/source/detour/include/detour/detour_interface.h @@ -2,7 +2,7 @@ * Detour Library by Parra Studios * A cross-platform library providing detours, function hooks and trampolines. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,8 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -42,10 +44,13 @@ typedef struct detour_interface_type *detour_interface; struct detour_interface_type { - detour_impl_handle (*initialize)(void); - int (*install)(detour_impl_handle, void (**)(void), void (*)(void)); - int (*uninstall)(detour_impl_handle); - int (*destroy)(detour_impl_handle); + int (*initialize_file)(detour_impl_handle *, const char *); + int (*initialize_handle)(detour_impl_handle *, dynlink); + int (*initialize_address)(detour_impl_handle *, void (*)(void)); + int (*enumerate)(detour_impl_handle, unsigned int *, const char **, void ***); + int (*replace)(detour_impl_handle, const char *, void (*)(void), void **); + const char *(*error)(detour_impl_handle); + void (*destroy)(detour_impl_handle); }; #ifdef __cplusplus diff --git a/source/detour/source/detour.c b/source/detour/source/detour.c index 3eeb57d6d6..c1e4646e01 100644 --- a/source/detour/source/detour.c +++ b/source/detour/source/detour.c @@ -1,6 +1,6 @@ /* * Detour Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library providing detours, function hooks and trampolines. * @@ -34,7 +34,13 @@ static plugin_manager_declare(detour_manager); struct detour_handle_type { - void (*target)(void); + /* TODO: Implement hash map for holding the symbol table? */ + /* TODO: Optimize the replace process by exposing the internal replace function + * and store all the symbols in the hash table then iterate and replace at the + * same time, so the functions are accessed in O(1) instead of O(n) + */ + set symbol_map; + set replaced_symbols; detour_impl_handle impl; }; @@ -65,32 +71,62 @@ const char *detour_name(detour d) return plugin_name(d); } -void (*detour_trampoline(detour_handle handle))(void) +static detour_handle detour_handle_allocate(void) { - return handle->target; + detour_handle handle = malloc(sizeof(struct detour_handle_type)); + + if (handle == NULL) + { + goto alloc_handle_error; + } + + handle->symbol_map = set_create(&hash_callback_ptr, &comparable_callback_ptr); + + if (handle->symbol_map == NULL) + { + goto alloc_symbol_map_error; + } + + handle->replaced_symbols = set_create(&hash_callback_ptr, &comparable_callback_ptr); + + if (handle->replaced_symbols == NULL) + { + goto alloc_replaced_symbols_error; + } + + handle->impl = NULL; + + return handle; + +alloc_replaced_symbols_error: + set_destroy(handle->symbol_map); +alloc_symbol_map_error: + free(handle); +alloc_handle_error: + return NULL; } -detour_handle detour_install(detour d, void (*target)(void), void (*hook)(void)) +detour_handle detour_load_file(detour d, const char *path) { - if (d == NULL || target == NULL || hook == NULL) + detour_handle handle; + + if (d == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour install arguments"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load arguments"); return NULL; } - detour_handle handle = malloc(sizeof(struct detour_handle_type)); + handle = detour_handle_allocate(); if (handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour install handle allocation"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load handle allocation"); return NULL; } - handle->impl = detour_iface(d)->initialize(); - - if (handle->impl == NULL) + if (detour_iface(d)->initialize_file(&handle->impl, path) != 0) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle initialization"); @@ -99,55 +135,112 @@ detour_handle detour_install(detour d, void (*target)(void), void (*hook)(void)) return NULL; } - void (**target_ptr)(void) = ⌖ + return handle; +} - if (detour_iface(d)->install(handle->impl, target_ptr, hook) != 0) +detour_handle detour_load_handle(detour d, dynlink library) +{ + detour_handle handle; + + if (d == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle installation"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load arguments"); - if (detour_iface(d)->destroy(handle->impl) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle destruction"); - } + return NULL; + } - free(handle); + handle = detour_handle_allocate(); + + if (handle == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load handle allocation"); return NULL; } - handle->target = *target_ptr; + if (detour_iface(d)->initialize_handle(&handle->impl, library) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle initialization"); + + free(handle); + + return NULL; + } return handle; } -int detour_uninstall(detour d, detour_handle handle) +detour_handle detour_load_address(detour d, void (*address)(void)) { - int result = 0; + detour_handle handle; + + if (d == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load arguments"); + + return NULL; + } + + handle = detour_handle_allocate(); + + if (handle == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour load handle allocation"); + + return NULL; + } + + if (detour_iface(d)->initialize_address(&handle->impl, address) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle initialization"); + + free(handle); + return NULL; + } + + return handle; +} + +int detour_enumerate(detour d, detour_handle handle, unsigned int *position, const char **name, void (***address)(void)) +{ if (d == NULL || handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid uninstall arguments"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour replace arguments"); return 1; } - result |= detour_iface(d)->uninstall(handle->impl); + return detour_iface(d)->enumerate(handle->impl, position, name, (void ***)address); +} - if (result != 0) +int detour_replace(detour d, detour_handle handle, const char *function_name, void (*function_addr)(void), void (**function_trampoline)(void)) +{ + if (d == NULL || handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle uninstallation"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour replace arguments"); + + return 1; } - result |= detour_iface(d)->destroy(handle->impl); + return detour_iface(d)->replace(handle->impl, function_name, function_addr, (void **)function_trampoline); +} - if (result != 0) +void detour_unload(detour d, detour_handle handle) +{ + if (d == NULL || handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour implementation handle destruction"); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid detour replace arguments"); + return; } - free(handle); + /* TODO: Should we restore all the replaced symbols? */ + + detour_iface(d)->destroy(handle->impl); + + set_destroy(handle->symbol_map); - return result; + set_destroy(handle->replaced_symbols); } int detour_clear(detour d) @@ -164,7 +257,7 @@ const char *detour_print_info(void) { static const char detour_info[] = "Detour Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef DETOUR_STATIC_DEFINE "Compiled as static library type" diff --git a/source/detours/CMakeLists.txt b/source/detours/CMakeLists.txt index 366f9f42ce..1a3c510302 100644 --- a/source/detours/CMakeLists.txt +++ b/source/detours/CMakeLists.txt @@ -1,10 +1,10 @@ # Check if detours are enabled -if(NOT OPTION_FORK_SAFE OR NOT OPTION_BUILD_DETOURS) +if(NOT OPTION_BUILD_DETOURS) return() endif() # Detour options -option(OPTION_BUILD_DETOURS_FUNCHOOK "FuncHook library detour." ON) +option(OPTION_BUILD_DETOURS_PLTHOOK "PLTHook library detour." ON) # Detour packages -add_subdirectory(funchook_detour) # FuncHook library +add_subdirectory(plthook_detour) # PLTHook library diff --git a/source/detours/funchook_detour/include/funchook_detour/funchook_detour_impl.h b/source/detours/funchook_detour/include/funchook_detour/funchook_detour_impl.h deleted file mode 100644 index 33b68d9e10..0000000000 --- a/source/detours/funchook_detour/include/funchook_detour/funchook_detour_impl.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Detour Library by Parra Studios - * A cross-platform library providing detours, function hooks and trampolines. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 FUNCHOOK_DETOUR_IMPL_H -#define FUNCHOOK_DETOUR_IMPL_H 1 - -/* -- Headers -- */ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Methods -- */ - -/** -* @brief -* Initialize FuncHook detour hook implementation -* -* @return -* Returns pointer to detour hook implementation on success, null pointer otherwise -* -*/ -FUNCHOOK_DETOUR_API detour_impl_handle funchook_detour_impl_initialize(void); - -/** -* @brief -* Install FuncHook detour implementation -* -* @param[in] handle -* Pointer to the detour hook implementation -* -* @param[in] target -* Pointer to the function to be intercepted -* -* @param[in] hook -* Function will be called instead of target -* -* @return -* Return zero on success, different from zero otherwise -* -*/ -FUNCHOOK_DETOUR_API int funchook_detour_impl_install(detour_impl_handle handle, void (**target)(void), void (*hook)(void)); - -/** -* @brief -* Uninstall FuncHook detour implementation -* -* @param[in] handle -* Pointer to the detour hook implementation -* -* @return -* Return zero on success, different from zero otherwise -* -*/ -FUNCHOOK_DETOUR_API int funchook_detour_impl_uninstall(detour_impl_handle handle); - -/** -* @brief -* Destroy FuncHook detour implementation -* -* @return -* Returns zero on correct destruction, distinct from zero otherwise -* -*/ -FUNCHOOK_DETOUR_API int funchook_detour_impl_destroy(detour_impl_handle handle); - -#ifdef __cplusplus -} -#endif - -#endif /* FUNCHOOK_DETOUR_IMPL_H */ diff --git a/source/detours/funchook_detour/scripts/download.bat.in b/source/detours/funchook_detour/scripts/download.bat.in deleted file mode 100755 index 8f1fd3842a..0000000000 --- a/source/detours/funchook_detour/scripts/download.bat.in +++ /dev/null @@ -1,12 +0,0 @@ -@echo on - -rem Download repository if it does not exist -if not exist @FUNCHOOK_SOURCE_DIR@/.git ( - if exist @FUNCHOOK_SOURCE_DIR@ ( - rmdir /S /Q "@FUNCHOOK_SOURCE_DIR@" - ) - "@GIT_EXECUTABLE@" clone --single-branch --branch v@FUNCHOOK_VERSION@ --recursive https://github.com/kubo/funchook.git @FUNCHOOK_SOURCE_DIR@ -) - -rem Write empty CMake file to avoid cmake warnings -copy /y nul "@FUNCHOOK_SOURCE_DIR@/CMakeLists.txt" diff --git a/source/detours/funchook_detour/scripts/download.sh.in b/source/detours/funchook_detour/scripts/download.sh.in deleted file mode 100755 index 946485c7bd..0000000000 --- a/source/detours/funchook_detour/scripts/download.sh.in +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env sh - -# Download repository if it does not exist -if [ ! -d @FUNCHOOK_SOURCE_DIR@/.git ] -then - if [ -d @FUNCHOOK_SOURCE_DIR@ ] - then - rm -rf @FUNCHOOK_SOURCE_DIR@ - fi - @GIT_EXECUTABLE@ clone --single-branch --branch v@FUNCHOOK_VERSION@ --recursive https://github.com/kubo/funchook.git @FUNCHOOK_SOURCE_DIR@ -fi diff --git a/source/detours/funchook_detour/source/funchook_detour.c b/source/detours/funchook_detour/source/funchook_detour.c deleted file mode 100644 index 93b6801652..0000000000 --- a/source/detours/funchook_detour/source/funchook_detour.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Detour Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * A cross-platform library providing detours, function hooks and trampolines. - * - */ - -/* -- Headers -- */ - -#include - -#include -#include - -/* -- Methods -- */ - -detour_interface funchook_detour_impl_interface_singleton(void) -{ - static struct detour_interface_type interface_instance_funchook = { - &funchook_detour_impl_initialize, - &funchook_detour_impl_install, - &funchook_detour_impl_uninstall, - &funchook_detour_impl_destroy - }; - - return &interface_instance_funchook; -} - -const char *funchook_detour_print_info(void) -{ - static const char funchook_detour_info[] = - "FuncHook Detour Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" - -#ifdef FUNCHOOK_DETOUR_STATIC_DEFINE - "Compiled as static library type\n" -#else - "Compiled as shared library type\n" -#endif - - "\n"; - - return funchook_detour_info; -} diff --git a/source/detours/funchook_detour/source/funchook_detour_impl.c b/source/detours/funchook_detour/source/funchook_detour_impl.c deleted file mode 100644 index 3eccf95451..0000000000 --- a/source/detours/funchook_detour/source/funchook_detour_impl.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Detour Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * A cross-platform library providing detours, function hooks and trampolines. - * - */ - -/* -- Headers -- */ - -#include - -#include - -#include - -/* -- Member Data -- */ - -union funchook_detour_impl_cast -{ - void (*hook)(void); - void *ptr; -}; - -/* -- Methods -- */ - -detour_impl_handle funchook_detour_impl_initialize(void) -{ - return (detour_impl_handle)funchook_create(); -} - -int funchook_detour_impl_install(detour_impl_handle handle, void (**target)(void), void (*hook)(void)) -{ - funchook_t *handle_impl = handle; - - if (handle_impl != NULL && target != NULL && hook != NULL) - { - union funchook_detour_impl_cast hook_cast = { hook }; - - if (funchook_prepare(handle_impl, (void **)target, hook_cast.ptr) != FUNCHOOK_ERROR_SUCCESS) - { - return 1; - } - - if (funchook_install(handle_impl, 0) != FUNCHOOK_ERROR_SUCCESS) - { - return 1; - } - - return 0; - } - - return 1; -} - -int funchook_detour_impl_uninstall(detour_impl_handle handle) -{ - funchook_t *handle_impl = handle; - - if (handle_impl != NULL) - { - return !(funchook_uninstall(handle_impl, 0) == FUNCHOOK_ERROR_SUCCESS); - } - - return 1; -} - -int funchook_detour_impl_destroy(detour_impl_handle handle) -{ - funchook_t *handle_impl = handle; - - if (handle_impl == NULL) - { - return 0; - } - - return !(funchook_destroy(handle_impl) == FUNCHOOK_ERROR_SUCCESS); -} diff --git a/source/detours/funchook_detour/CMakeLists.txt b/source/detours/plthook_detour/CMakeLists.txt similarity index 50% rename from source/detours/funchook_detour/CMakeLists.txt rename to source/detours/plthook_detour/CMakeLists.txt index b9c304e1dc..0907b84fa5 100644 --- a/source/detours/funchook_detour/CMakeLists.txt +++ b/source/detours/plthook_detour/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if this detour is enabled -if(NOT OPTION_FORK_SAFE OR NOT OPTION_BUILD_DETOURS OR NOT OPTION_BUILD_DETOURS_FUNCHOOK) +if(NOT OPTION_BUILD_DETOURS OR NOT OPTION_BUILD_DETOURS_PLTHOOK) return() endif() @@ -7,68 +7,37 @@ endif() # External dependencies # -find_package(Git REQUIRED) +# PLTHook +if(NOT PLTHook_SOURCE_DIR) + include(FetchContent) -# Target depends name -set(target_depends funchook_detour_depends) + set(PLTHook_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/plthook") -include(ExternalProject) + FetchContent_Declare(PLTHook + GIT_REPOSITORY https://github.com/metacall/plthook.git + GIT_TAG master + SOURCE_DIR ${PLTHook_SOURCE_DIR} + ) -set(FUNCHOOK_VERSION 1.1.3) - -if(WIN32) - set(FUNCHOOK_LIBRARY_PREFIX "") - set(FUNCHOOK_LIBRARY_SUFFIX "lib") - set(FUNCHOOK_LIBRARY_INSTALL_SUFFIX "dll") -elseif(APPLE) - set(FUNCHOOK_LIBRARY_PREFIX "lib") - set(FUNCHOOK_LIBRARY_SUFFIX "dylib") - set(FUNCHOOK_LIBRARY_INSTALL_SUFFIX "dylib") -else() - set(FUNCHOOK_LIBRARY_PREFIX "lib") - set(FUNCHOOK_LIBRARY_SUFFIX "so") - set(FUNCHOOK_LIBRARY_INSTALL_SUFFIX "so") + FetchContent_MakeAvailable(PLTHook) endif() -set(FUNCHOOK_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/funchook/src/funchook") +set(PLTHook_INCLUDE_DIR "${PLTHook_SOURCE_DIR}") -if(WIN32) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/download.bat.in ${CMAKE_CURRENT_BINARY_DIR}/download.bat @ONLY) - set(FUNCHOOK_DOWNLOAD_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/download.bat) - set(FUNCHOOK_BUILD_TARGET "INSTALL") +if(APPLE) + set(PLTHook_SOURCE "${PLTHook_SOURCE_DIR}/plthook_osx.c") +elseif(WIN32 OR MINGW) + set(PLTHook_SOURCE "${PLTHook_SOURCE_DIR}/plthook_win32.c") else() - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/download.sh.in ${CMAKE_CURRENT_BINARY_DIR}/download.sh @ONLY) - set(FUNCHOOK_DOWNLOAD_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/download.sh) - set(FUNCHOOK_BUILD_TARGET "install") + set(PLTHook_SOURCE "${PLTHook_SOURCE_DIR}/plthook_elf.c") endif() -set(FUNCHOOK_INSTALL_DIR "${PROJECT_OUTPUT_DIR}") -set(FUNCHOOK_INCLUDE_DIR "${FUNCHOOK_SOURCE_DIR}/include") -set(FUNCHOOK_LIBRARY_DIR "${FUNCHOOK_SOURCE_DIR}/${FUNCHOOK_LIBRARY_PREFIX}funchook.${FUNCHOOK_LIBRARY_SUFFIX}") -set(FUNCHOOK_LIBRARY_INSTALL_DIR "${FUNCHOOK_SOURCE_DIR}/${FUNCHOOK_LIBRARY_PREFIX}funchook.${FUNCHOOK_LIBRARY_INSTALL_SUFFIX}") - -ExternalProject_Add( - ${target_depends} - PREFIX funchook - SOURCE_DIR ${FUNCHOOK_SOURCE_DIR} - INSTALL_DIR ${FUNCHOOK_INSTALL_DIR} - DOWNLOAD_COMMAND ${FUNCHOOK_DOWNLOAD_COMMAND} - CONFIGURE_COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_BUILD_PARALLEL_LEVEL=1 -DCMAKE_PLATFORM_NO_VERSIONED_SONAME=ON -DCMAKE_INSTALL_PREFIX=${FUNCHOOK_INSTALL_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DFUNCHOOK_BUILD_SHARED=ON -DFUNCHOOK_BUILD_TESTS=OFF -DFUNCHOOK_BUILD_STATIC=OFF . - BUILD_COMMAND ${CMAKE_COMMAND} -E env CMAKE_BUILD_PARALLEL_LEVEL=1 ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE} --target ${FUNCHOOK_BUILD_TARGET} - UPDATE_COMMAND "" - BUILD_IN_SOURCE ON - LOG_DOWNLOAD ON - LOG_CONFIGURE ON - LOG_BUILD ON - LOG_INSTALL ON -) - # # Library name and options # # Target name -set(target funchook_detour) +set(target plthook_detour) # Exit here if required dependencies are not met message(STATUS "Detour ${target}") @@ -98,13 +67,14 @@ set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(headers - ${include_path}/funchook_detour.h - ${include_path}/funchook_detour_impl.h + ${include_path}/plthook_detour.h + ${include_path}/plthook_detour_impl.h ) set(sources - ${source_path}/funchook_detour.c - ${source_path}/funchook_detour_impl.c + ${source_path}/plthook_detour.c + ${source_path}/plthook_detour_impl.c + ${PLTHook_SOURCE} # PLTHook Source ) # Group source files @@ -125,11 +95,6 @@ add_library(${target} MODULE ${headers} ) -# Add target dependencies -add_dependencies(${target} - ${target_depends} -) - # Create namespaced alias add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) @@ -164,7 +129,7 @@ target_include_directories(${target} ${CMAKE_CURRENT_BINARY_DIR}/include $ # MetaCall includes - ${FUNCHOOK_INCLUDE_DIR} # FuncHook includes + ${PLTHook_INCLUDE_DIR} # PLTHook includes PUBLIC ${DEFAULT_INCLUDE_DIRECTORIES} @@ -182,7 +147,6 @@ target_include_directories(${target} target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library - ${FUNCHOOK_LIBRARY_DIR} # FuncHook libraries PUBLIC ${DEFAULT_LIBRARIES} @@ -221,7 +185,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC @@ -236,7 +200,6 @@ target_link_libraries(${target} # Dependency install(FILES - ${FUNCHOOK_LIBRARY_INSTALL_DIR} DESTINATION ${INSTALL_LIB} COMPONENT runtime ) diff --git a/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h b/source/detours/plthook_detour/include/plthook_detour/plthook_detour.h similarity index 68% rename from source/detours/funchook_detour/include/funchook_detour/funchook_detour.h rename to source/detours/plthook_detour/include/plthook_detour/plthook_detour.h index b1967f77df..068ae11c6e 100644 --- a/source/detours/funchook_detour/include/funchook_detour/funchook_detour.h +++ b/source/detours/plthook_detour/include/plthook_detour/plthook_detour.h @@ -2,7 +2,7 @@ * Detour Library by Parra Studios * A cross-platform library providing detours, function hooks and trampolines. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,15 @@ * */ -#ifndef FUNCHOOK_DETOUR_H -#define FUNCHOOK_DETOUR_H 1 +#ifndef PLTHOOK_DETOUR_H +#define PLTHOOK_DETOUR_H 1 /* -- Headers -- */ -#include +#include #include -#include - #ifdef __cplusplus extern "C" { #endif @@ -43,9 +41,7 @@ extern "C" { * Returns pointer to interface to be used by implementation * */ -FUNCHOOK_DETOUR_API detour_interface funchook_detour_impl_interface_singleton(void); - -DYNLINK_SYMBOL_EXPORT(funchook_detour_impl_interface_singleton); +PLTHOOK_DETOUR_API detour_interface plthook_detour_impl_interface_singleton(void); /** * @brief @@ -55,12 +51,10 @@ DYNLINK_SYMBOL_EXPORT(funchook_detour_impl_interface_singleton); * Static string containing module information * */ -FUNCHOOK_DETOUR_API const char *funchook_detour_print_info(void); - -DYNLINK_SYMBOL_EXPORT(funchook_detour_print_info); +PLTHOOK_DETOUR_API const char *plthook_detour_print_info(void); #ifdef __cplusplus } #endif -#endif /* FUNCHOOK_DETOUR_H */ +#endif /* PLTHOOK_DETOUR_H */ diff --git a/source/detours/plthook_detour/include/plthook_detour/plthook_detour_impl.h b/source/detours/plthook_detour/include/plthook_detour/plthook_detour_impl.h new file mode 100644 index 0000000000..680cff01e0 --- /dev/null +++ b/source/detours/plthook_detour/include/plthook_detour/plthook_detour_impl.h @@ -0,0 +1,151 @@ +/* + * Detour Library by Parra Studios + * A cross-platform library providing detours, function hooks and trampolines. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 PLTHOOK_DETOUR_IMPL_H +#define PLTHOOK_DETOUR_IMPL_H 1 + +/* -- Headers -- */ + +#include + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Methods -- */ + +/** +* @brief +* Initialize PLTHook detour hook implementation by file name +* +* @param[out] handle +* When success, it returns the pointer to the detour implementation, null otherwise +* +* @param[in] path +* String containing the path or name to the dynamic library to be opened +* +* @return +* Returns zero on success, different from zero otherwise +* +*/ +PLTHOOK_DETOUR_API int plthook_detour_impl_initialize_file(detour_impl_handle *handle, const char *path); + +/** +* @brief +* Initialize PLTHook detour hook implementation by already l +* +* @param[out] handle +* When success, it returns the pointer to the detour implementation, null otherwiseoaded dynamic library handle +* +* @param[in] library +* Pointer to the dynlink handle of the library +* +* @return +* Returns zero on success, different from zero otherwise +* +*/ +PLTHOOK_DETOUR_API int plthook_detour_impl_initialize_handle(detour_impl_handle *handle, dynlink library); + +/** +* @brief +* Initialize PLTHook detour hook implementation by a functio +* +* @param[out] handle +* When success, it returns the pointer to the detour implementation, null otherwisen pointer of a function belonging to a library +* +* @param[in] address +* Function pointer of a function belonging to the library to be hooked +* +* @return +* Returns zero on success, different from zero otherwise +* +*/ +PLTHOOK_DETOUR_API int plthook_detour_impl_initialize_address(detour_impl_handle *handle, void (*address)(void)); + +/** +* @brief +* Iterate all symbols of the library already opened +* +* @param[in] handle +* Pointer to the detour hook implementation +* +* @param[out] position +* Pointer to the current index of the enumeration +* +* @param[out] name +* Pointer to the function name in string form +* +* @param[out] address +* Pointer to the pointer of the function pointer of the function to be hooked +* +* @return +* Return zero on success, different from zero otherwise +* +*/ +PLTHOOK_DETOUR_API int plthook_detour_impl_enumerate(detour_impl_handle handle, unsigned int *position, const char **name, void ***address); + +/** +* @brief +* Replace function from a library already opened by name, returns the old function pointer +* +* @param[in] handle +* Pointer to the detour hook implementation +* +* @param[in] function_name +* String containing the function name to be replaced +* +* @param[in] function_addr +* Function pointer that will be used to replace the original one +* +* @param[out] function_old_addr +* Function pointer to the original function that has been replaced +* +* @return +* Return zero on success, different from zero otherwise +* +*/ +PLTHOOK_DETOUR_API int plthook_detour_impl_replace(detour_impl_handle handle, const char *function_name, void (*function_addr)(void), void **function_old_addr); + +/** +* @brief +* Error handling PLTHook detour implementation +* +* @return +* Returns string containing the information of the error +* +*/ +PLTHOOK_DETOUR_API const char *plthook_detour_impl_error(detour_impl_handle handle); + +/** +* @brief +* Destroy PLTHook detour implementation +* +*/ +PLTHOOK_DETOUR_API void plthook_detour_impl_destroy(detour_impl_handle handle); + +#ifdef __cplusplus +} +#endif + +#endif /* PLTHOOK_DETOUR_IMPL_H */ diff --git a/source/detours/plthook_detour/source/plthook_detour.c b/source/detours/plthook_detour/source/plthook_detour.c new file mode 100644 index 0000000000..b291b0b8e2 --- /dev/null +++ b/source/detours/plthook_detour/source/plthook_detour.c @@ -0,0 +1,48 @@ +/* + * Detour Library by Parra Studios + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * A cross-platform library providing detours, function hooks and trampolines. + * + */ + +/* -- Headers -- */ + +#include + +#include +#include + +/* -- Methods -- */ + +detour_interface plthook_detour_impl_interface_singleton(void) +{ + static struct detour_interface_type interface_instance_plthook = { + &plthook_detour_impl_initialize_file, + &plthook_detour_impl_initialize_handle, + &plthook_detour_impl_initialize_address, + &plthook_detour_impl_enumerate, + &plthook_detour_impl_replace, + &plthook_detour_impl_error, + &plthook_detour_impl_destroy + }; + + return &interface_instance_plthook; +} + +const char *plthook_detour_print_info(void) +{ + static const char plthook_detour_info[] = + "PLTHook Detour Plugin " METACALL_VERSION "\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" + +#ifdef PLTHOOK_DETOUR_STATIC_DEFINE + "Compiled as static library type\n" +#else + "Compiled as shared library type\n" +#endif + + "\n"; + + return plthook_detour_info; +} diff --git a/source/detours/plthook_detour/source/plthook_detour_impl.c b/source/detours/plthook_detour/source/plthook_detour_impl.c new file mode 100644 index 0000000000..33d23850d3 --- /dev/null +++ b/source/detours/plthook_detour/source/plthook_detour_impl.c @@ -0,0 +1,122 @@ +/* + * Detour Library by Parra Studios + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * A cross-platform library providing detours, function hooks and trampolines. + * + */ + +/* -- Headers -- */ + +#include + +#include + +/* -- Methods -- */ + +int plthook_detour_impl_initialize_file(detour_impl_handle *handle, const char *path) +{ + plthook_t *plthook; + int result; + + if (handle == NULL) + { + return 1; + } + + result = plthook_open(&plthook, path); + + if (result != PLTHOOK_SUCCESS) + { + *handle = NULL; + return result; + } + + *handle = (void *)plthook; + return 0; +} + +int plthook_detour_impl_initialize_handle(detour_impl_handle *handle, dynlink library) +{ + plthook_t *plthook; + int result; + + if (handle == NULL) + { + return 1; + } + + result = plthook_open_by_handle(&plthook, dynlink_get_impl(library)); + + if (result != PLTHOOK_SUCCESS) + { + *handle = NULL; + return result; + } + + *handle = (void *)plthook; + return 0; +} + +int plthook_detour_impl_initialize_address(detour_impl_handle *handle, void (*address)(void)) + +{ + plthook_t *plthook; + void *ptr; + int result; + + if (handle == NULL) + { + return 1; + } + + dynlink_symbol_uncast(address, ptr); + + result = plthook_open_by_address(&plthook, ptr); + + if (result != PLTHOOK_SUCCESS) + { + *handle = NULL; + return result; + } + + *handle = (void *)plthook; + return 0; +} + +int plthook_detour_impl_enumerate(detour_impl_handle handle, unsigned int *position, const char **name, void ***address) +{ + if (handle == NULL) + { + return 1; + } + + return plthook_enum(handle, position, name, address); +} + +int plthook_detour_impl_replace(detour_impl_handle handle, const char *function_name, void (*function_addr)(void), void **function_old_addr) +{ + void *ptr; + + if (handle == NULL) + { + return 1; + } + + dynlink_symbol_uncast(function_addr, ptr); + + return plthook_replace(handle, function_name, ptr, function_old_addr); +} + +const char *plthook_detour_impl_error(detour_impl_handle handle) +{ + /* TODO: The error should be stored in the handle, this must be modified from plthook library itself */ + (void)handle; + + return plthook_error(); +} + +void plthook_detour_impl_destroy(detour_impl_handle handle) +{ + plthook_close(handle); +} diff --git a/source/dynlink/CMakeLists.txt b/source/dynlink/CMakeLists.txt index 0c1bd92942..8a9d6aed61 100644 --- a/source/dynlink/CMakeLists.txt +++ b/source/dynlink/CMakeLists.txt @@ -47,9 +47,7 @@ set(headers ${include_path}/dynlink.h ${include_path}/dynlink_flags.h ${include_path}/dynlink_impl.h - ${include_path}/dynlink_impl_symbol_${DYNLINK_IMPL_INTERFACE_NAME}.h ${include_path}/dynlink_impl_${DYNLINK_IMPL_INTERFACE_NAME}.h - ${include_path}/dynlink_symbol.h ) set(sources @@ -57,7 +55,6 @@ set(sources ${source_path}/dynlink_impl.c ${source_path}/dynlink_impl_${DYNLINK_IMPL_INTERFACE_NAME}.c ${source_path}/dynlink_interface.c - ${source_path}/dynlink_symbol.c ) # Group source files @@ -171,7 +168,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/dynlink/include/dynlink/dynlink.h b/source/dynlink/include/dynlink/dynlink.h index 2b42705a6c..1a94636f0f 100644 --- a/source/dynlink/include/dynlink/dynlink.h +++ b/source/dynlink/include/dynlink/dynlink.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -37,6 +36,15 @@ extern "C" { /* -- Methods -- */ +/** +* @brief +* Get the library prefix for specified platform (normally "lib") +* +* @return +* A constant string pointer to the platform prefix +*/ +DYNLINK_API const char *dynlink_prefix(void); + /** * @brief * Get the library extension for specified platform @@ -62,7 +70,34 @@ DYNLINK_API const char *dynlink_extension(void); * @return * A handle to the dynamically linked shared object */ -DYNLINK_API dynlink dynlink_load(dynlink_path path, dynlink_name name, dynlink_flags flags); +DYNLINK_API dynlink dynlink_load(const char *path, const char *name, dynlink_flags flags); + +/** +* @brief +* Load a dynamically linked shared object with absolute path +* +* @param[in] path +* Path where is located the shared object (absolute) +* +* @param[in] flags +* Dynamic linking flags +* +* @return +* A handle to the dynamically linked shared object +*/ +DYNLINK_API dynlink dynlink_load_absolute(const char *path, dynlink_flags flags); + +/** +* @brief +* Get the reference of the current process +* +* @param[in] flags +* Dynamic linking flags +* +* @return +* A handle to the current process +*/ +DYNLINK_API dynlink dynlink_load_self(dynlink_flags flags); /** * @brief @@ -74,19 +109,19 @@ DYNLINK_API dynlink dynlink_load(dynlink_path path, dynlink_name name, dynlink_f * @return * Reference to the name of the dynamically linked shared object */ -DYNLINK_API dynlink_name dynlink_get_name(dynlink handle); +DYNLINK_API const char *dynlink_get_name(dynlink handle); /** * @brief -* Retreive the file name of the dynamically linked shared object handle +* Retreive the path of the dynamically linked shared object handle * * @param[in] handle * Handle of dynamically linked shared object * * @return -* Reference to the file name of the dynamically linked shared object +* Reference to the path of the dynamically linked shared object */ -DYNLINK_API dynlink_name dynlink_get_name_impl(dynlink handle); +DYNLINK_API const char *dynlink_get_path(dynlink handle); /** * @brief @@ -100,6 +135,18 @@ DYNLINK_API dynlink_name dynlink_get_name_impl(dynlink handle); */ DYNLINK_API dynlink_flags dynlink_get_flags(dynlink handle); +/** +* @brief +* Retreive the internal representation of the dynamically linked shared object +* +* @param[in] handle +* Handle of dynamically linked shared object +* +* @return +* The implementation dependant handle representing the dynamically linked shared object +*/ +DYNLINK_API dynlink_impl dynlink_get_impl(dynlink handle); + /** * @brief * Get a symbol address of dynamically linked shared object by name @@ -116,7 +163,7 @@ DYNLINK_API dynlink_flags dynlink_get_flags(dynlink handle); * @return * Returns zero on correct dynamic linking, distinct from zero otherwise */ -DYNLINK_API int dynlink_symbol(dynlink handle, dynlink_symbol_name symbol_name, dynlink_symbol_addr *symbol_address); +DYNLINK_API int dynlink_symbol(dynlink handle, const char *symbol_name, dynlink_symbol_addr *symbol_address); /** * @brief @@ -143,7 +190,7 @@ DYNLINK_API void dynlink_unload(dynlink handle); * @return * Returns zero if it could find the path, different from zero if not found */ -DYNLINK_API int dynlink_library_path(dynlink_name name, dynlink_library_path_str path, size_t *length); +DYNLINK_API int dynlink_library_path(const char *name, dynlink_path path, size_t *length); /** * @brief @@ -155,7 +202,7 @@ DYNLINK_API int dynlink_library_path(dynlink_name name, dynlink_library_path_str * @param[out] result * The resulting library name that will be generated (i.e libexample.so in Linux, or example.dll in Windows) */ -DYNLINK_API void dynlink_platform_name(dynlink_name name, dynlink_name_impl result); +DYNLINK_API void dynlink_platform_name(const char *name, dynlink_path result); /** * @brief diff --git a/source/dynlink/include/dynlink/dynlink_flags.h b/source/dynlink/include/dynlink/dynlink_flags.h index 9b870abae8..f72708a27e 100644 --- a/source/dynlink/include/dynlink/dynlink_flags.h +++ b/source/dynlink/include/dynlink/dynlink_flags.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,8 @@ extern "C" { #define DYNLINK_FLAGS_BIND_LOCAL (0x01 << 0x02) /**< Private visibility bind flag */ #define DYNLINK_FLAGS_BIND_GLOBAL (0x01 << 0x03) /**< Public visibility bind flag */ +#define DYNLINK_FLAGS_BIND_SELF (0x01 << 0x10) /**< Private flag for when loading the current process */ + /* -- Macros -- */ /** diff --git a/source/dynlink/include/dynlink/dynlink_impl.h b/source/dynlink/include/dynlink/dynlink_impl.h index 3185db4aac..d5d8728e64 100644 --- a/source/dynlink/include/dynlink/dynlink_impl.h +++ b/source/dynlink/include/dynlink/dynlink_impl.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,12 +33,17 @@ extern "C" { #endif -/* -- Headers -- */ - -#include - /* -- Methods -- */ +/** +* @brief +* Dynamically linked shared object handle prefix implementation (normally "lib") +* +* @return +* A const string reference to the prefix depending on the OS implementation +*/ +DYNLINK_API const char *dynlink_impl_prefix(void); + /** * @brief * Dynamically linked shared object handle extension implementation @@ -55,19 +60,19 @@ DYNLINK_API const char *dynlink_impl_extension(void); * @param[in] name * Name of dynamically linked shared object * -* @param[out] name_impl -* Pointer to the dynamically linked shared object handle +* @param[out] destination +* Pointer to string where final platform dependant name will be stored * * @param[in] size -* Size of string @name_impl +* Size of string @destination */ -DYNLINK_API void dynlink_impl_get_name(dynlink_name name, dynlink_name_impl name_impl, size_t size); +DYNLINK_API void dynlink_impl_get_name(const char *name, dynlink_path destination, size_t size); /** * @brief * Load a dynamically linked shared object implementation * -* @param[in] name +* @param[in] handle * Pointer to the dynamically linked shared object handle * * @return @@ -94,7 +99,7 @@ DYNLINK_API dynlink_impl dynlink_impl_load(dynlink handle); * @return * Returns zero on correct dynamic linking, distinct from zero otherwise */ -DYNLINK_API int dynlink_impl_symbol(dynlink handle, dynlink_impl impl, dynlink_symbol_name symbol_name, dynlink_symbol_addr *symbol_address); +DYNLINK_API int dynlink_impl_symbol(dynlink handle, dynlink_impl impl, const char *symbol_name, dynlink_symbol_addr *symbol_address); /** * @brief diff --git a/source/dynlink/include/dynlink/dynlink_impl_beos.h b/source/dynlink/include/dynlink/dynlink_impl_beos.h index f77adbb3ee..52b2bea368 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_beos.h +++ b/source/dynlink/include/dynlink/dynlink_impl_beos.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_macos.h b/source/dynlink/include/dynlink/dynlink_impl_macos.h index d2bce45dd4..51a7ec6cb2 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_macos.h +++ b/source/dynlink/include/dynlink/dynlink_impl_macos.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h deleted file mode 100644 index 6530fd895b..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_beos.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 DYNLINK_IMPL_SYMBOL_BEOS_H -#define DYNLINK_IMPL_SYMBOL_BEOS_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_beos_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_beos_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_beos)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_beos_impl)(void); - -typedef struct dynlink_symbol_addr_beos_type -{ - dynlink_symbol_addr_beos_impl symbol; -} * dynlink_symbol_addr_beos; - -typedef dynlink_symbol_addr_beos dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_BEOS_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h deleted file mode 100644 index 7d92286e65..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_macos.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 DYNLINK_IMPL_SYMBOL_MACOS_H -#define DYNLINK_IMPL_SYMBOL_MACOS_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_macos_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_macos_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_macos)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_macos_impl)(void); - -typedef struct dynlink_symbol_addr_macos_type -{ - dynlink_symbol_addr_macos_impl symbol; -} * dynlink_symbol_addr_macos; - -typedef dynlink_symbol_addr_macos dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_MACOS_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h deleted file mode 100644 index 56a66a91b3..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_unix.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 DYNLINK_IMPL_SYMBOL_UNIX_H -#define DYNLINK_IMPL_SYMBOL_UNIX_H 1 - -/* -- Headers -- */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX \ - dynlink_symbol_ - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_API struct dynlink_symbol_addr_unix_type DYNLINK_SYMBOL_NAME(name) = { \ - (dynlink_symbol_addr_unix_impl)&name \ - } - -#define DYNLINK_SYMBOL_GET(name) \ - ((dynlink_symbol_addr_unix)(name))->symbol - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_unix_impl)(void); - -typedef struct dynlink_symbol_addr_unix_type -{ - dynlink_symbol_addr_unix_impl symbol; -} * dynlink_symbol_addr_unix; - -typedef dynlink_symbol_addr_unix dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_UNIX_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h deleted file mode 100644 index 670ece3712..0000000000 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 DYNLINK_IMPL_SYMBOL_WIN32_H -#define DYNLINK_IMPL_SYMBOL_WIN32_H 1 - -/* -- Headers -- */ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_PREFIX - -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_NO_EXPORT struct \ - { \ - char name; \ - } PREPROCESSOR_CONCAT(dynlink_no_export_, name) - -#define DYNLINK_SYMBOL_GET(name) name - -/* -- Type definitions -- */ - -typedef void (*dynlink_symbol_addr_win32)(void); - -typedef dynlink_symbol_addr_win32 dynlink_symbol_addr; - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_IMPL_SYMBOL_WIN32_H */ diff --git a/source/dynlink/include/dynlink/dynlink_impl_unix.h b/source/dynlink/include/dynlink/dynlink_impl_unix.h index 7cd53898b8..972b23c903 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_unix.h +++ b/source/dynlink/include/dynlink/dynlink_impl_unix.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_impl_win32.h b/source/dynlink/include/dynlink/dynlink_impl_win32.h index 17daeb7112..a44fb9d821 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_win32.h +++ b/source/dynlink/include/dynlink/dynlink_impl_win32.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/source/dynlink/include/dynlink/dynlink_interface.h b/source/dynlink/include/dynlink/dynlink_interface.h index b0f710c032..445a0cd4d4 100644 --- a/source/dynlink/include/dynlink/dynlink_interface.h +++ b/source/dynlink/include/dynlink/dynlink_interface.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,18 +28,14 @@ #include #if defined(WIN32) || defined(_WIN32) - #include #include #elif defined(unix) || defined(__unix__) || defined(__unix) || \ defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ (((defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__)) && (defined(MAC_OS_X_VERSION_10_15) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15))) - #include #include #elif (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) - #include #include #elif defined(__HAIKU__) || defined(__BEOS__) - #include #include #else #error "Unsupported platform for dynlink" @@ -50,41 +46,24 @@ #include #include -#include - #ifdef __cplusplus extern "C" { #endif -/* -- Macros -- */ - -#define DYNLINK_SYMBOL_PREFIX_STR() \ - PREPROCESSOR_STRINGIFY_OR_EMPTY(DYNLINK_SYMBOL_PREFIX) - -#define DYNLINK_SYMBOL_NAME(name) \ - PREPROCESSOR_CONCAT(DYNLINK_SYMBOL_PREFIX, name) - -#define DYNLINK_SYMBOL_NAME_STR(name) \ - PREPROCESSOR_STRINGIFY(DYNLINK_SYMBOL_NAME(name)) - -#define DYNLINK_SYMBOL_STR(name) \ - DYNLINK_SYMBOL_PREFIX_STR() \ - name - /* -- Type definitions -- */ typedef dynlink_symbol_addr *dynlink_symbol_addr_ptr; +typedef const char *(*dynlink_impl_interface_prefix)(void); typedef const char *(*dynlink_impl_interface_extension)(void); -typedef void (*dynlink_impl_interface_get_name)(dynlink_name, dynlink_name_impl, size_t); typedef dynlink_impl (*dynlink_impl_interface_load)(dynlink); -typedef int (*dynlink_impl_interface_symbol)(dynlink, dynlink_impl, dynlink_symbol_name, dynlink_symbol_addr_ptr); +typedef int (*dynlink_impl_interface_symbol)(dynlink, dynlink_impl, const char *, dynlink_symbol_addr_ptr); typedef int (*dynlink_impl_interface_unload)(dynlink, dynlink_impl); struct dynlink_impl_interface_type { + dynlink_impl_interface_prefix prefix; dynlink_impl_interface_extension extension; - dynlink_impl_interface_get_name get_name; dynlink_impl_interface_load load; dynlink_impl_interface_symbol symbol; dynlink_impl_interface_unload unload; diff --git a/source/dynlink/include/dynlink/dynlink_symbol.h b/source/dynlink/include/dynlink/dynlink_symbol.h deleted file mode 100644 index d0319663f5..0000000000 --- a/source/dynlink/include/dynlink/dynlink_symbol.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 DYNLINK_SYMBOL_H -#define DYNLINK_SYMBOL_H 1 - -/* -- Headers -- */ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Definitions -- */ - -#define DYNLINK_SYMBOL_NAME_SIZE 0xFF - -/* -- Type Definitions -- */ - -typedef char dynlink_symbol_name_man[DYNLINK_SYMBOL_NAME_SIZE]; - -/* -- Methods -- */ - -/** -* @brief -* Get convert a symbol to name mangled for cross-platform dynamic loading -* -* @param[in] symbol_name -* Reference to name of the of dynamically linked shared object symbol -* -* @param[out] symbol_mangled -* Reference to mangled name of the of dynamically linked shared object symbol -* -* @return -* Returns zero if @symbol_name was correctly mangled -*/ -DYNLINK_API size_t dynlink_symbol_name_mangle(dynlink_symbol_name symbol_name, size_t symbol_name_length, dynlink_symbol_name_man symbol_mangled); - -#ifdef __cplusplus -} -#endif - -#endif /* DYNLINK_H */ diff --git a/source/dynlink/include/dynlink/dynlink_type.h b/source/dynlink/include/dynlink/dynlink_type.h index c883ec2dab..57413cae25 100644 --- a/source/dynlink/include/dynlink/dynlink_type.h +++ b/source/dynlink/include/dynlink/dynlink_type.h @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,13 +37,54 @@ struct dynlink_type; /* -- Type definitions -- */ -typedef struct dynlink_type *dynlink; /**< Dynamically linked shared object handle */ -typedef const char *dynlink_path; /**< Dynamically linked shared object path */ -typedef const char *dynlink_name; /**< Dynamically linked shared object name */ -typedef const char *dynlink_symbol_name; /**< Dynamically linked shared object symbol name */ -typedef portability_library_path_str dynlink_library_path_str; /**< Dynamically linked shared object symbol name */ -typedef void *dynlink_impl; /**< Dynamically linked shared object implementation */ -typedef char dynlink_name_impl[PORTABILITY_PATH_SIZE]; /**< Allocated copy of dynamically linked shared object name */ +typedef struct dynlink_type *dynlink; /**< Dynamically linked shared object handle */ +typedef void *dynlink_impl; /**< Dynamically linked shared object implementation */ +typedef char dynlink_path[PORTABILITY_PATH_SIZE]; /**< Allocated copy of dynamically linked shared object name */ +typedef void (*dynlink_symbol_addr)(void); /**< Function pointer referring to a symbol address */ + +/* -- Macros -- */ + +#define dynlink_symbol_cast(type, symbol, result) \ + do \ + { \ + union \ + { \ + type ptr; \ + dynlink_symbol_addr fn; \ + } cast; \ +\ + cast.ptr = (symbol); \ + (result) = cast.fn; \ +\ + } while (0) + +#define dynlink_symbol_uncast(fn, result) \ + do \ + { \ + union \ + { \ + void *ptr; \ + dynlink_symbol_addr fn; \ + } cast; \ +\ + cast.fn = (fn); \ + (result) = cast.ptr; \ +\ + } while (0) + +#define dynlink_symbol_uncast_type(fn, type, result) \ + do \ + { \ + union \ + { \ + type ptr; \ + dynlink_symbol_addr fn; \ + } cast; \ +\ + cast.fn = (fn); \ + (result) = (type)cast.ptr; \ +\ + } while (0) #ifdef __cplusplus } diff --git a/source/dynlink/source/dynlink.c b/source/dynlink/source/dynlink.c index 4ae3b801d4..216c18d37b 100644 --- a/source/dynlink/source/dynlink.c +++ b/source/dynlink/source/dynlink.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -34,20 +35,25 @@ struct dynlink_type { - dynlink_name_impl name; /**< Dynamically linked shared object name */ - dynlink_name_impl name_impl; /**< Dynamically linked shared object file name */ - dynlink_flags flags; /**< Dynamically linked shared object flags */ - dynlink_impl impl; /**< Dynamically linked shared object loader implementation */ + dynlink_path name; /**< Dynamically linked shared object name */ + dynlink_path path; /**< Dynamically linked shared object file name */ + dynlink_flags flags; /**< Dynamically linked shared object flags */ + dynlink_impl impl; /**< Dynamically linked shared object loader implementation */ }; /* -- Methods -- */ +const char *dynlink_prefix(void) +{ + return dynlink_impl_prefix(); +} + const char *dynlink_extension(void) { return dynlink_impl_extension(); } -dynlink dynlink_load(dynlink_path path, dynlink_name name, dynlink_flags flags) +dynlink dynlink_load(const char *path, const char *name, dynlink_flags flags) { if (name != NULL) { @@ -55,26 +61,26 @@ dynlink dynlink_load(dynlink_path path, dynlink_name name, dynlink_flags flags) if (handle != NULL) { - dynlink_name_impl name_impl; + dynlink_path name_impl; strncpy(handle->name, name, PORTABILITY_PATH_SIZE - 1); - dynlink_impl_get_name(dynlink_get_name(handle), name_impl, PORTABILITY_PATH_SIZE); + dynlink_impl_get_name(handle->name, name_impl, PORTABILITY_PATH_SIZE); if (path != NULL) { - dynlink_name_impl join_path; + dynlink_path join_path; size_t join_path_size = portability_path_join(path, strnlen(path, PORTABILITY_PATH_SIZE) + 1, name_impl, strnlen(name_impl, PORTABILITY_PATH_SIZE) + 1, join_path, PORTABILITY_PATH_SIZE); - (void)portability_path_canonical(join_path, join_path_size, handle->name_impl, PORTABILITY_PATH_SIZE); + (void)portability_path_canonical(join_path, join_path_size, handle->path, PORTABILITY_PATH_SIZE); } else { - strncpy(handle->name_impl, name_impl, strnlen(name_impl, PORTABILITY_PATH_SIZE) + 1); + strncpy(handle->path, name_impl, strnlen(name_impl, PORTABILITY_PATH_SIZE) + 1); } - handle->flags = flags; + DYNLINK_FLAGS_SET(handle->flags, flags); handle->impl = dynlink_impl_load(handle); @@ -90,7 +96,85 @@ dynlink dynlink_load(dynlink_path path, dynlink_name name, dynlink_flags flags) return NULL; } -dynlink_name dynlink_get_name(dynlink handle) +dynlink dynlink_load_absolute(const char *path, dynlink_flags flags) +{ + dynlink handle = malloc(sizeof(struct dynlink_type)); + size_t path_size, name_size, prefix_length; + const char *prefix = dynlink_prefix(); + + if (handle == NULL) + { + return NULL; + } + + path_size = strnlen(path, PORTABILITY_PATH_SIZE) + 1; + + strncpy(handle->path, path, path_size); + + /* Get the library name without any extension */ + name_size = portability_path_get_name_canonical(path, path_size, handle->name, PORTABILITY_PATH_SIZE); + + /* Remove the library prefix */ + prefix_length = strlen(prefix); + + if (strncmp(prefix, handle->name, prefix_length) == 0) + { + size_t current, next = prefix_length, end = name_size - prefix_length; + + for (current = 0; current < end; ++current, ++next) + { + handle->name[current] = handle->name[next]; + } + } + + DYNLINK_FLAGS_SET(handle->flags, flags); + + handle->impl = dynlink_impl_load(handle); + + if (handle->impl == NULL) + { + free(handle); + return NULL; + } + + return handle; +} + +dynlink dynlink_load_self(dynlink_flags flags) +{ + portability_executable_path_length path_length; + dynlink handle = malloc(sizeof(struct dynlink_type)); + + if (handle == NULL) + { + return NULL; + } + + /* Retrieve the executable path for the full name */ + portability_executable_path(handle->path, &path_length); + + /* Get the name without the extension */ + portability_path_get_name(handle->path, path_length + 1, handle->name, PORTABILITY_PATH_SIZE); + + /* Set the flags with the additional special flag for itself, + this will help to identify that the handle loaded is the current executable + and behave accordingly depending on the implementation + */ + DYNLINK_FLAGS_SET(handle->flags, flags); + DYNLINK_FLAGS_ADD(handle->flags, DYNLINK_FLAGS_BIND_SELF); + + handle->impl = dynlink_impl_load(handle); + + if (handle->impl == NULL) + { + free(handle); + return NULL; + } + + return handle; +} + +const char *dynlink_get_name(dynlink handle) { if (handle != NULL) { @@ -100,11 +184,11 @@ dynlink_name dynlink_get_name(dynlink handle) return NULL; } -dynlink_name dynlink_get_name_impl(dynlink handle) +const char *dynlink_get_path(dynlink handle) { if (handle != NULL) { - return handle->name_impl; + return handle->path; } return NULL; @@ -120,7 +204,17 @@ dynlink_flags dynlink_get_flags(dynlink handle) return 0; } -int dynlink_symbol(dynlink handle, dynlink_symbol_name symbol_name, dynlink_symbol_addr *symbol_address) +dynlink_impl dynlink_get_impl(dynlink handle) +{ + if (handle != NULL) + { + return handle->impl; + } + + return NULL; +} + +int dynlink_symbol(dynlink handle, const char *symbol_name, dynlink_symbol_addr *symbol_address) { if (handle != NULL && handle->impl != NULL && symbol_name != NULL && symbol_address != NULL) { @@ -140,13 +234,13 @@ void dynlink_unload(dynlink handle) } } -int dynlink_library_path(dynlink_name name, dynlink_library_path_str path, size_t *length) +int dynlink_library_path(const char *name, dynlink_path path, size_t *length) { - dynlink_name_impl name_impl; + dynlink_path name_impl; dynlink_impl_get_name(name, name_impl, PORTABILITY_PATH_SIZE); - if (portability_library_path(name_impl, path, length) != 0) + if (portability_library_path_find(name_impl, path, length) != 0) { return 1; } @@ -157,13 +251,13 @@ int dynlink_library_path(dynlink_name name, dynlink_library_path_str path, size_ } else { - (void)portability_path_get_directory_inplace(path, strnlen(path, sizeof(dynlink_library_path_str) / sizeof(char)) + 1); + (void)portability_path_get_directory_inplace(path, strnlen(path, PORTABILITY_PATH_SIZE)); } return 0; } -void dynlink_platform_name(dynlink_name name, dynlink_name_impl result) +void dynlink_platform_name(const char *name, dynlink_path result) { dynlink_impl_get_name(name, result, PORTABILITY_PATH_SIZE); } @@ -172,7 +266,7 @@ const char *dynlink_print_info(void) { static const char dynlink_info[] = "Dynamic Link Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef DYNLINK_STATIC_DEFINE "Compiled as static library type" diff --git a/source/dynlink/source/dynlink_impl.c b/source/dynlink/source/dynlink_impl.c index 2c2da41e6e..f49fece5c8 100644 --- a/source/dynlink/source/dynlink_impl.c +++ b/source/dynlink/source/dynlink_impl.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,13 @@ /* -- Methods -- */ +const char *dynlink_impl_prefix(void) +{ + dynlink_impl_interface_singleton_ptr singleton = dynlink_interface(); + + return singleton()->prefix(); +} + const char *dynlink_impl_extension(void) { dynlink_impl_interface_singleton_ptr singleton = dynlink_interface(); @@ -35,13 +42,17 @@ const char *dynlink_impl_extension(void) return singleton()->extension(); } -void dynlink_impl_get_name(dynlink_name name, dynlink_name_impl name_impl, size_t size) +void dynlink_impl_get_name(const char *name, dynlink_path destination, size_t size) { - if (name != NULL && name_impl != NULL && size > 1) + if (name != NULL && destination != NULL && size > 1) { - dynlink_impl_interface_singleton_ptr singleton = dynlink_interface(); + strncpy(destination, dynlink_impl_prefix(), size); + + strncat(destination, name, size - 1); + + strncat(destination, ".", size - 1); - singleton()->get_name(name, name_impl, size); + strncat(destination, dynlink_impl_extension(), size - 1); } } @@ -52,7 +63,7 @@ dynlink_impl dynlink_impl_load(dynlink handle) return singleton()->load(handle); } -int dynlink_impl_symbol(dynlink handle, dynlink_impl impl, dynlink_symbol_name symbol_name, dynlink_symbol_addr *symbol_address) +int dynlink_impl_symbol(dynlink handle, dynlink_impl impl, const char *symbol_name, dynlink_symbol_addr *symbol_address) { if (impl != NULL) { diff --git a/source/dynlink/source/dynlink_impl_beos.c b/source/dynlink/source/dynlink_impl_beos.c index 8ce81828f5..98d5a07ccb 100644 --- a/source/dynlink/source/dynlink_impl_beos.c +++ b/source/dynlink/source/dynlink_impl_beos.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,47 +31,53 @@ /* -- Methods -- */ -const char *dynlink_impl_interface_extension_beos(void) +const char *dynlink_impl_interface_prefix_beos(void) { - static const char extension_beos[] = "so"; + static const char prefix_beos[] = "lib"; - return extension_beos; + return prefix_beos; } -void dynlink_impl_interface_get_name_beos(dynlink_name name, dynlink_name_impl name_impl, size_t size) +const char *dynlink_impl_interface_extension_beos(void) { - strncpy(name_impl, "lib", size); - - strncat(name_impl, name, size - 1); - - strncat(name_impl, ".", size - 1); + static const char extension_beos[] = "so"; - strncat(name_impl, dynlink_impl_extension(), size - 1); + return extension_beos; } dynlink_impl dynlink_impl_interface_load_beos(dynlink handle) { dynlink_flags flags = dynlink_get_flags(handle); + image_id impl = 0; - int flags_impl; - - image_id impl; + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + image_info info; + int32 cookie = 0; - DYNLINK_FLAGS_SET(flags_impl, 0); + if (get_next_image_info(0, &cookie, &info) != B_OK) + { + log_write("metacall", LOG_LEVEL_ERROR, "DynLink error: failed to load BeOS/Haiku image add-on on current executable"); + return NULL; + } - impl = load_add_on(dynlink_get_name_impl(handle)); + impl = load_add_on(info.name); + } + else + { + impl = load_add_on(dynlink_get_path(handle)); + } if (impl < B_NO_ERROR) { - return (dynlink_impl)impl; + log_write("metacall", LOG_LEVEL_ERROR, "DynLink error: failed to load BeOS/Haiku image add-on with error code %d", (int)impl); + return NULL; } - log_write("metacall", LOG_LEVEL_ERROR, "DynLink error: failed to load BeOS/Haiku image add-on"); - - return NULL; + return (dynlink_impl)impl; } -int dynlink_impl_interface_symbol_beos(dynlink handle, dynlink_impl impl, dynlink_symbol_name name, dynlink_symbol_addr *addr) +int dynlink_impl_interface_symbol_beos(dynlink handle, dynlink_impl impl, const char *name, dynlink_symbol_addr *addr) { void *symbol = NULL; @@ -85,15 +91,23 @@ int dynlink_impl_interface_symbol_beos(dynlink handle, dynlink_impl impl, dynlin return 1; } - *addr = (dynlink_symbol_addr)symbol; + dynlink_symbol_cast(void *, symbol, *addr); return (*addr == NULL); } int dynlink_impl_interface_unload_beos(dynlink handle, dynlink_impl impl) { + dynlink_flags flags = dynlink_get_flags(handle); + (void)handle; + /* Skip unlink when using global handle for loading symbols of the current process */ + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + return 0; + } + #if defined(__MEMORYCHECK__) || defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ (void)impl; @@ -106,8 +120,8 @@ int dynlink_impl_interface_unload_beos(dynlink handle, dynlink_impl impl) dynlink_impl_interface dynlink_impl_interface_singleton(void) { static struct dynlink_impl_interface_type impl_interface_beos = { + &dynlink_impl_interface_prefix_beos, &dynlink_impl_interface_extension_beos, - &dynlink_impl_interface_get_name_beos, &dynlink_impl_interface_load_beos, &dynlink_impl_interface_symbol_beos, &dynlink_impl_interface_unload_beos, diff --git a/source/dynlink/source/dynlink_impl_macos.c b/source/dynlink/source/dynlink_impl_macos.c index 6447c73902..48c7a4daf1 100644 --- a/source/dynlink/source/dynlink_impl_macos.c +++ b/source/dynlink/source/dynlink_impl_macos.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,86 +32,92 @@ #include +/* -- Member Data -- */ + +static void *dynlink_impl_global_handle_macos = NULL; + /* -- Methods -- */ -const char *dynlink_impl_interface_extension_macos(void) +const char *dynlink_impl_interface_prefix_macos(void) { - static const char extension_macos[] = "dylib"; + static const char prefix_macos[] = "lib"; - return extension_macos; + return prefix_macos; } -void dynlink_impl_interface_get_name_macos(dynlink_name name, dynlink_name_impl name_impl, size_t size) +const char *dynlink_impl_interface_extension_macos(void) { - strncpy(name_impl, name, size); - - strncat(name_impl, ".", size - 1); + static const char extension_macos[] = "dylib"; - strncat(name_impl, dynlink_impl_extension(), size - 1); + return extension_macos; } dynlink_impl dynlink_impl_interface_load_macos(dynlink handle) { dynlink_flags flags = dynlink_get_flags(handle); - - unsigned long flags_impl; - - NSObjectFileImage image; - NSModule impl; - const char *name = dynlink_get_name_impl(handle); - - NSObjectFileImageReturnCode ret = NSCreateObjectFileImageFromFile(name, &image); - - if (ret != NSObjectFileImageSuccess) + if (!DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) { - char *error; + unsigned long flags_impl; + NSObjectFileImage image; + const char *name = dynlink_get_path(handle); + NSObjectFileImageReturnCode ret = NSCreateObjectFileImageFromFile(name, &image); - switch (ret) + if (ret != NSObjectFileImageSuccess) { - case NSObjectFileImageAccess: - if (access(name, F_OK) == 0) - { - error = "DynLink error: %s permission denied"; - } - else - { - error = "DynLink error: %s no such file or directory"; - } - case NSObjectFileImageArch: - error = "DynLink error: %s is not built for the current architecture"; - break; - case NSObjectFileImageInappropriateFile: - case NSObjectFileImageFormat: - error = "DynLink error: %s is not a loadable module"; - break; - default: - error = "DynLink error: unknown error for %s"; - break; + char *error; + + switch (ret) + { + case NSObjectFileImageAccess: + if (access(name, F_OK) == 0) + { + error = "DynLink error: %s permission denied"; + } + else + { + error = "DynLink error: %s no such file or directory"; + } + case NSObjectFileImageArch: + error = "DynLink error: %s is not built for the current architecture"; + break; + case NSObjectFileImageInappropriateFile: + case NSObjectFileImageFormat: + error = "DynLink error: %s is not a loadable module"; + break; + default: + error = "DynLink error: unknown error for %s"; + break; + } + + log_write("metacall", LOG_LEVEL_ERROR, error, name); + + return NULL; } - log_write("metacall", LOG_LEVEL_ERROR, error, name); + DYNLINK_FLAGS_SET(flags_impl, NSLINKMODULE_OPTION_RETURN_ON_ERROR); - return NULL; - } + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_LOCAL)) + { + DYNLINK_FLAGS_ADD(flags_impl, NSLINKMODULE_OPTION_PRIVATE); + } + + if (!DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_LAZY)) + { + DYNLINK_FLAGS_ADD(flags_impl, NSLINKMODULE_OPTION_BINDNOW); + } - DYNLINK_FLAGS_SET(flags_impl, NSLINKMODULE_OPTION_RETURN_ON_ERROR); + impl = NSLinkModule(image, name, flags_impl); - if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_LOCAL)) - { - DYNLINK_FLAGS_ADD(flags_impl, NSLINKMODULE_OPTION_PRIVATE); + NSDestroyObjectFileImage(image); } - - if (!DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_LAZY)) + else { - DYNLINK_FLAGS_ADD(flags_impl, NSLINKMODULE_OPTION_BINDNOW); + /* We return this for identifying the global handle when loading symbols of the current process */ + impl = (void *)(&dynlink_impl_global_handle_macos); } - impl = NSLinkModule(image, name, flags_impl); - - NSDestroyObjectFileImage(image); - if (impl == NULL) { NSLinkEditErrors link_edit_errors; @@ -130,29 +136,63 @@ dynlink_impl dynlink_impl_interface_load_macos(dynlink handle) return (dynlink_impl)impl; } -int dynlink_impl_interface_symbol_macos(dynlink handle, dynlink_impl impl, dynlink_symbol_name name, dynlink_symbol_addr *addr) +int dynlink_impl_interface_symbol_macos(dynlink handle, dynlink_impl impl, const char *name, dynlink_symbol_addr *addr) { - NSSymbol symbol = NSLookupSymbolInModule(impl, name); + dynlink_flags flags = dynlink_get_flags(handle); + NSSymbol symbol; + void *symbol_addr; (void)handle; - *addr = (dynlink_symbol_addr)NSAddressOfSymbol(symbol); + /* Skip unlink when using global handle for loading symbols of the current process */ + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + /* Global context, use NSLookupAndBindSymbol */ + if (!NSIsSymbolNameDefined(name)) + { + return 1; + } + + symbol = NSLookupAndBindSymbol(name); + } + else + { + symbol = NSLookupSymbolInModule(impl, name); + } + + symbol_addr = NSAddressOfSymbol(symbol); + + dynlink_symbol_cast(void *, symbol_addr, *addr); return (*addr == NULL); } int dynlink_impl_interface_unload_macos(dynlink handle, dynlink_impl impl) { + dynlink_flags flags = dynlink_get_flags(handle); + (void)handle; + /* Skip unlink when using global handle for loading symbols of the current process */ + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + return 0; + } + +#if defined(__MEMORYCHECK__) || defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) + /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ + (void)impl; + return 0; +#else return NSUnLinkModule(impl, 0) == TRUE ? 0 : 1; +#endif } dynlink_impl_interface dynlink_impl_interface_singleton(void) { static struct dynlink_impl_interface_type impl_interface_macos = { + &dynlink_impl_interface_prefix_macos, &dynlink_impl_interface_extension_macos, - &dynlink_impl_interface_get_name_macos, &dynlink_impl_interface_load_macos, &dynlink_impl_interface_symbol_macos, &dynlink_impl_interface_unload_macos, diff --git a/source/dynlink/source/dynlink_impl_unix.c b/source/dynlink/source/dynlink_impl_unix.c index a6455dd648..7a6d35711a 100644 --- a/source/dynlink/source/dynlink_impl_unix.c +++ b/source/dynlink/source/dynlink_impl_unix.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,41 +28,28 @@ #include -#ifndef _GNU_SOURCE - #define _GNU_SOURCE -#endif -#ifndef __USE_GNU - #define __USE_GNU -#endif - #include /* -- Methods -- */ -const char *dynlink_impl_interface_extension_unix(void) +const char *dynlink_impl_interface_prefix_unix(void) { - static const char extension_unix[] = "so"; + static const char prefix_unix[] = "lib"; - return extension_unix; + return prefix_unix; } -void dynlink_impl_interface_get_name_unix(dynlink_name name, dynlink_name_impl name_impl, size_t size) +const char *dynlink_impl_interface_extension_unix(void) { - strncpy(name_impl, "lib", size); - - strncat(name_impl, name, size - 1); - - strncat(name_impl, ".", size - 1); + static const char extension_unix[] = "so"; - strncat(name_impl, dynlink_impl_extension(), size - 1); + return extension_unix; } dynlink_impl dynlink_impl_interface_load_unix(dynlink handle) { dynlink_flags flags = dynlink_get_flags(handle); - int flags_impl; - void *impl; DYNLINK_FLAGS_SET(flags_impl, 0); @@ -87,33 +74,48 @@ dynlink_impl dynlink_impl_interface_load_unix(dynlink handle) DYNLINK_FLAGS_ADD(flags_impl, RTLD_GLOBAL); } - impl = dlopen(dynlink_get_name_impl(handle), flags_impl); - - if (impl != NULL) + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + impl = dlopen(NULL, flags_impl); + } + else { - return (dynlink_impl)impl; + impl = dlopen(dynlink_get_path(handle), flags_impl); } - log_write("metacall", LOG_LEVEL_ERROR, "DynLink error: %s", dlerror()); + if (impl == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "DynLink error: %s", dlerror()); + + return NULL; + } - return NULL; + return (dynlink_impl)impl; } -int dynlink_impl_interface_symbol_unix(dynlink handle, dynlink_impl impl, dynlink_symbol_name name, dynlink_symbol_addr *addr) +int dynlink_impl_interface_symbol_unix(dynlink handle, dynlink_impl impl, const char *name, dynlink_symbol_addr *addr) { void *symbol = dlsym(impl, name); (void)handle; - *addr = (dynlink_symbol_addr)symbol; + dynlink_symbol_cast(void *, symbol, *addr); return (*addr == NULL); } int dynlink_impl_interface_unload_unix(dynlink handle, dynlink_impl impl) { + dynlink_flags flags = dynlink_get_flags(handle); + (void)handle; + /* Skip unlink when using global handle for loading symbols of the current process */ + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + return 0; + } + #if defined(__MEMORYCHECK__) || defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) /* Disable dlclose when running with valgrind or sanitizers in order to maintain stacktraces */ (void)impl; @@ -126,8 +128,8 @@ int dynlink_impl_interface_unload_unix(dynlink handle, dynlink_impl impl) dynlink_impl_interface dynlink_impl_interface_singleton(void) { static struct dynlink_impl_interface_type impl_interface_unix = { + &dynlink_impl_interface_prefix_unix, &dynlink_impl_interface_extension_unix, - &dynlink_impl_interface_get_name_unix, &dynlink_impl_interface_load_unix, &dynlink_impl_interface_symbol_unix, &dynlink_impl_interface_unload_unix, diff --git a/source/dynlink/source/dynlink_impl_win32.c b/source/dynlink/source/dynlink_impl_win32.c index 8ea74bb24f..d1956a9654 100644 --- a/source/dynlink/source/dynlink_impl_win32.c +++ b/source/dynlink/source/dynlink_impl_win32.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,25 +32,37 @@ /* -- Methods -- */ -const char *dynlink_impl_interface_extension_win32(void) +const char *dynlink_impl_interface_prefix_win32(void) { - static const char extension_win32[] = "dll"; +#if defined(__MINGW32__) || defined(__MINGW64__) + static const char prefix_win32[] = "lib"; +#else + static const char prefix_win32[] = ""; +#endif - return extension_win32; + return prefix_win32; } -void dynlink_impl_interface_get_name_win32(dynlink_name name, dynlink_name_impl name_impl, size_t size) +const char *dynlink_impl_interface_extension_win32(void) { - strncpy(name_impl, name, size); - - strncat(name_impl, ".", size - 1); + static const char extension_win32[] = "dll"; - strncat(name_impl, dynlink_impl_extension(), size - 1); + return extension_win32; } dynlink_impl dynlink_impl_interface_load_win32(dynlink handle) { - HANDLE impl = LoadLibrary(dynlink_get_name_impl(handle)); + HMODULE impl; + dynlink_flags flags = dynlink_get_flags(handle); + + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + impl = GetModuleHandle(NULL); + } + else + { + impl = LoadLibrary(dynlink_get_path(handle)); + } if (impl == NULL) { @@ -60,7 +72,7 @@ dynlink_impl dynlink_impl_interface_load_win32(dynlink handle) size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message_buffer, 0, NULL); - log_write("metacall", LOG_LEVEL_ERROR, "Failed to load: %s with error code [%d]: %.*s", dynlink_get_name_impl(handle), error_id, size - 1, (const char *)message_buffer); + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load: %s with error code [%d]: %.*s", dynlink_get_path(handle), error_id, size - 1, (const char *)message_buffer); LocalFree(message_buffer); @@ -70,29 +82,43 @@ dynlink_impl dynlink_impl_interface_load_win32(dynlink handle) return (dynlink_impl)impl; } -int dynlink_impl_interface_symbol_win32(dynlink handle, dynlink_impl impl, dynlink_symbol_name name, dynlink_symbol_addr *addr) +int dynlink_impl_interface_symbol_win32(dynlink handle, dynlink_impl impl, const char *name, dynlink_symbol_addr *addr) { FARPROC proc_addr = GetProcAddress(impl, name); (void)handle; - *addr = (dynlink_symbol_addr)proc_addr; + dynlink_symbol_cast(FARPROC, proc_addr, *addr); return (*addr == NULL); } int dynlink_impl_interface_unload_win32(dynlink handle, dynlink_impl impl) { + dynlink_flags flags = dynlink_get_flags(handle); + (void)handle; + /* Skip unlink when using global handle for loading symbols of the current process */ + if (DYNLINK_FLAGS_CHECK(flags, DYNLINK_FLAGS_BIND_SELF)) + { + return 0; + } + +#if defined(__MEMORYCHECK__) || defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) + /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ + (void)impl; + return 0; +#else return (FreeLibrary(impl) == FALSE); +#endif } dynlink_impl_interface dynlink_impl_interface_singleton(void) { static struct dynlink_impl_interface_type impl_interface_win32 = { + &dynlink_impl_interface_prefix_win32, &dynlink_impl_interface_extension_win32, - &dynlink_impl_interface_get_name_win32, &dynlink_impl_interface_load_win32, &dynlink_impl_interface_symbol_win32, &dynlink_impl_interface_unload_win32, diff --git a/source/dynlink/source/dynlink_interface.c b/source/dynlink/source/dynlink_interface.c index f35642217e..adc7b623aa 100644 --- a/source/dynlink/source/dynlink_interface.c +++ b/source/dynlink/source/dynlink_interface.c @@ -2,7 +2,7 @@ * Dynamic Link Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/dynlink/source/dynlink_symbol.c b/source/dynlink/source/dynlink_symbol.c deleted file mode 100644 index 35ac3861d7..0000000000 --- a/source/dynlink/source/dynlink_symbol.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Dynamic Link Library by Parra Studios - * A library for dynamic loading and linking shared objects at run-time. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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. - * - */ - -/* -- Headers -- */ - -#include -#include - -#include - -/* -- Methods -- */ - -size_t dynlink_symbol_name_mangle(dynlink_symbol_name symbol_name, size_t symbol_name_length, dynlink_symbol_name_man symbol_mangled) -{ - static const char symbol_prefix[] = DYNLINK_SYMBOL_PREFIX_STR(); - static size_t symbol_prefix_length = sizeof(symbol_prefix) - 1; - size_t length = symbol_name_length + symbol_prefix_length; - - if (symbol_mangled == NULL) - { - return length; - } - - if (symbol_prefix_length > 0) - { - memcpy(symbol_mangled, symbol_prefix, symbol_prefix_length); - } - - memcpy(&symbol_mangled[symbol_prefix_length], symbol_name, symbol_name_length); - - symbol_mangled[length] = '\0'; - - return length; -} diff --git a/source/environment/CMakeLists.txt b/source/environment/CMakeLists.txt index 243a97849d..28b99aa951 100644 --- a/source/environment/CMakeLists.txt +++ b/source/environment/CMakeLists.txt @@ -150,7 +150,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/environment/include/environment/environment.h b/source/environment/include/environment/environment.h index fab2ee2beb..7646f3f823 100644 --- a/source/environment/include/environment/environment.h +++ b/source/environment/include/environment/environment.h @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/environment/include/environment/environment_variable.h b/source/environment/include/environment/environment_variable.h index 11332c09ac..730dc3c857 100644 --- a/source/environment/include/environment/environment_variable.h +++ b/source/environment/include/environment/environment_variable.h @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/environment/include/environment/environment_variable_path.h b/source/environment/include/environment/environment_variable_path.h index 5b5f83da4b..5f3a17ba44 100644 --- a/source/environment/include/environment/environment_variable_path.h +++ b/source/environment/include/environment/environment_variable_path.h @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +52,29 @@ 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 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. + * + * @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 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). + * + * @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.c b/source/environment/source/environment.c index ae95bac494..e5c3270e8a 100644 --- a/source/environment/source/environment.c +++ b/source/environment/source/environment.c @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ const char *environment_print_info(void) { static const char environment_info[] = "Format Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef LOG_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/environment/source/environment_variable.c b/source/environment/source/environment_variable.c index d608cee434..a9e94eb23f 100644 --- a/source/environment/source/environment_variable.c +++ b/source/environment/source/environment_variable.c @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,7 +77,7 @@ const char *environment_variable_get(const char *name, const char *default_value int environment_variable_set(const char *name, const char *value_string) { -#if defined(_WIN32) +#if defined(WIN32) || defined(_WIN32) return _putenv_s(name, value_string); #else return setenv(name, value_string, 1); diff --git a/source/environment/source/environment_variable_path.c b/source/environment/source/environment_variable_path.c index 8bfd3d50c0..813112a807 100644 --- a/source/environment/source/environment_variable_path.c +++ b/source/environment/source/environment_variable_path.c @@ -2,7 +2,7 @@ * Environment Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,59 +43,53 @@ /* -- 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); + const char *env_variable = getenv(name); char *path; - size_t length, size, last, end; + size_t size, alloc_size; - if (path_ptr == NULL) + if (env_variable) { - 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; + size = strlen(env_variable) + 1; + } + else if (default_path) + { + env_variable = default_path; + size = default_path_size; } else { - length = strlen(path_ptr); + env_variable = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR; + size = sizeof(ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR); } - last = length - 1; + alloc_size = size; - if (ENVIRONMENT_VARIABLE_PATH_SEPARATOR(path_ptr[last])) - { - end = length; - size = length + 1; - } - else + if (size > 1) { - last = length; - end = length + 1; - size = length + 2; + alloc_size += !ENVIRONMENT_VARIABLE_PATH_SEPARATOR(env_variable[size - 2]); } - path = malloc(sizeof(char) * size); + path = malloc(sizeof(char) * alloc_size); if (path == NULL) { return NULL; } - strncpy(path, path_ptr, length); + memcpy(path, env_variable, sizeof(char) * size); + + if (size > 1) + { + path[alloc_size - 2] = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_C; + } - path[last] = ENVIRONMENT_VARIABLE_PATH_SEPARATOR_C; - path[end] = '\0'; + path[alloc_size - 1] = '\0'; - if (env_size != NULL) + if (env_size) { - *env_size = size; + *env_size = alloc_size; } return path; diff --git a/source/examples/metacallgui/CMakeLists.txt b/source/examples/metacallgui/CMakeLists.txt index 5ad9757906..485521f882 100644 --- a/source/examples/metacallgui/CMakeLists.txt +++ b/source/examples/metacallgui/CMakeLists.txt @@ -125,7 +125,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/examples/metacalllog/CMakeLists.txt b/source/examples/metacalllog/CMakeLists.txt index 5a4c04da4c..6b4f8d234f 100644 --- a/source/examples/metacalllog/CMakeLists.txt +++ b/source/examples/metacalllog/CMakeLists.txt @@ -93,7 +93,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/examples/metacalllog/main.cpp b/source/examples/metacalllog/main.cpp index e7b47deea5..397d6bf371 100644 --- a/source/examples/metacalllog/main.cpp +++ b/source/examples/metacalllog/main.cpp @@ -2,7 +2,7 @@ * MetaCall Log by Parra Studios * Example of advanced logging in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,5 +143,7 @@ int main(int, char *[]) /* Here you can load some scripts */ - return metacall_destroy(); + metacall_destroy(); + + return 0; } diff --git a/source/examples/metacallquine/CMakeLists.txt b/source/examples/metacallquine/CMakeLists.txt index 9254a6b796..0da78c404f 100644 --- a/source/examples/metacallquine/CMakeLists.txt +++ b/source/examples/metacallquine/CMakeLists.txt @@ -112,7 +112,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/examples/metacallquine/main.cpp b/source/examples/metacallquine/main.cpp index a06008caff..639d69e77b 100644 --- a/source/examples/metacallquine/main.cpp +++ b/source/examples/metacallquine/main.cpp @@ -2,7 +2,7 @@ * MetaCall Quine by Parra Studios * A quine relay proof of concept intercomunicating between multiple programming languages. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/examples/metacallweb/CMakeLists.txt b/source/examples/metacallweb/CMakeLists.txt index 7e6a5f7feb..6c81c8b2e1 100644 --- a/source/examples/metacallweb/CMakeLists.txt +++ b/source/examples/metacallweb/CMakeLists.txt @@ -99,7 +99,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/examples/metacallweb/main.cpp b/source/examples/metacallweb/main.cpp index f9f1cbb1e4..e82ba481a6 100644 --- a/source/examples/metacallweb/main.cpp +++ b/source/examples/metacallweb/main.cpp @@ -2,7 +2,7 @@ * MetaCall Web Service by Parra Studios * A complete web service example using metacall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/extensions/plugin_extension/CMakeLists.txt b/source/extensions/plugin_extension/CMakeLists.txt index 0ef36ecd17..31baf3fbae 100644 --- a/source/extensions/plugin_extension/CMakeLists.txt +++ b/source/extensions/plugin_extension/CMakeLists.txt @@ -161,7 +161,7 @@ target_compile_features(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h b/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h index ef5d86dc55..f009d33426 100644 --- a/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h +++ b/source/extensions/plugin_extension/include/plugin_extension/plugin_extension.h @@ -2,7 +2,7 @@ * Extension Library by Parra Studios * An extension for loading a folder of plugins based on metacall.json files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif PLUGIN_EXTENSION_API int plugin_extension(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(plugin_extension); - #ifdef __cplusplus } #endif diff --git a/source/extensions/plugin_extension/source/plugin_extension.cpp b/source/extensions/plugin_extension/source/plugin_extension.cpp index 3035b2b9e7..eac0a32c5b 100644 --- a/source/extensions/plugin_extension/source/plugin_extension.cpp +++ b/source/extensions/plugin_extension/source/plugin_extension.cpp @@ -2,7 +2,7 @@ * Extension Library by Parra Studios * An extension for loading a folder of plugins based on metacall.json files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ namespace fs = std::experimental::filesystem; static void *extension_loader = NULL; -void *plugin_load_from_path(size_t argc, void *args[], void *data) +static void *plugin_load_from_path(size_t argc, void *args[], void *data) { /* TODO: Improve return values with throwable in the future */ (void)data; diff --git a/source/filesystem/CMakeLists.txt b/source/filesystem/CMakeLists.txt index 397193fde4..56024183dd 100644 --- a/source/filesystem/CMakeLists.txt +++ b/source/filesystem/CMakeLists.txt @@ -181,7 +181,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/filesystem/include/filesystem/filesystem.h b/source/filesystem/include/filesystem/filesystem.h index 1bcc454f9d..0fead82850 100644 --- a/source/filesystem/include/filesystem/filesystem.h +++ b/source/filesystem/include/filesystem/filesystem.h @@ -2,7 +2,7 @@ * File System Library by Parra Studios * A cross-platform library for managing file system, paths and files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/filesystem/include/filesystem/filesystem_directory_descriptor.h b/source/filesystem/include/filesystem/filesystem_directory_descriptor.h index e4315e3f39..358329de2f 100644 --- a/source/filesystem/include/filesystem/filesystem_directory_descriptor.h +++ b/source/filesystem/include/filesystem/filesystem_directory_descriptor.h @@ -2,7 +2,7 @@ * File System Library by Parra Studios * A cross-platform library for managing file system, paths and files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/filesystem/include/filesystem/filesystem_file_descriptor.h b/source/filesystem/include/filesystem/filesystem_file_descriptor.h index 65469a983c..043be0534a 100644 --- a/source/filesystem/include/filesystem/filesystem_file_descriptor.h +++ b/source/filesystem/include/filesystem/filesystem_file_descriptor.h @@ -2,7 +2,7 @@ * File System Library by Parra Studios * A cross-platform library for managing file system, paths and files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/filesystem/source/filesystem.c b/source/filesystem/source/filesystem.c index 47d17ec11c..b9e2df00f1 100644 --- a/source/filesystem/source/filesystem.c +++ b/source/filesystem/source/filesystem.c @@ -1,6 +1,6 @@ /* * File System Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A cross-platform library for managing file system, paths and files. * @@ -154,7 +154,7 @@ const char *filesystem_print_info(void) { static const char filesystem_info[] = "File System Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef FILESYSTEM_STATIC_DEFINE "Compiled as static library type" diff --git a/source/filesystem/source/filesystem_directory_descriptor.c b/source/filesystem/source/filesystem_directory_descriptor.c index 22d531fe1f..7d7f161544 100644 --- a/source/filesystem/source/filesystem_directory_descriptor.c +++ b/source/filesystem/source/filesystem_directory_descriptor.c @@ -2,7 +2,7 @@ * File System Library by Parra Studios * A cross-platform library for managing file system, paths and files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/filesystem/source/filesystem_file_descriptor.c b/source/filesystem/source/filesystem_file_descriptor.c index 04f92c9eb8..f03603279b 100644 --- a/source/filesystem/source/filesystem_file_descriptor.c +++ b/source/filesystem/source/filesystem_file_descriptor.c @@ -2,7 +2,7 @@ * File System Library by Parra Studios * A cross-platform library for managing file system, paths and files. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/format/CMakeLists.txt b/source/format/CMakeLists.txt index d9f880e1a1..1bf3e2c7f8 100644 --- a/source/format/CMakeLists.txt +++ b/source/format/CMakeLists.txt @@ -147,7 +147,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/format/include/format/format.h b/source/format/include/format/format.h index 239a1c74d4..81138d96b2 100644 --- a/source/format/include/format/format.h +++ b/source/format/include/format/format.h @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/format/include/format/format_print.h b/source/format/include/format/format_print.h index 0ad41f5a6b..c30f995e84 100644 --- a/source/format/include/format/format_print.h +++ b/source/format/include/format/format_print.h @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/format/include/format/format_specifier.h b/source/format/include/format/format_specifier.h index ff9344e571..947c51eb43 100644 --- a/source/format/include/format/format_specifier.h +++ b/source/format/include/format/format_specifier.h @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/format/source/format.c b/source/format/source/format.c index ef5deb66f4..cf35393df5 100644 --- a/source/format/source/format.c +++ b/source/format/source/format.c @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ const char *format_print_info(void) { static const char format_info[] = "Format Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef FORMAT_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loader/CMakeLists.txt b/source/loader/CMakeLists.txt index 852575a607..953a5f3ef7 100644 --- a/source/loader/CMakeLists.txt +++ b/source/loader/CMakeLists.txt @@ -170,7 +170,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loader/include/loader/loader.h b/source/loader/include/loader/loader.h index b7fec73ec5..d209315391 100644 --- a/source/loader/include/loader/loader.h +++ b/source/loader/include/loader/loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,10 +33,6 @@ extern "C" { #endif -/* -- Headers -- */ - -#include - /* -- Forward Declarations -- */ struct loader_type; @@ -45,8 +41,6 @@ struct loader_type; typedef value (*loader_register_invoke)(size_t, void *[], void *); -typedef void *loader_data; - typedef struct loader_type *loader; /* -- Methods -- */ @@ -61,6 +55,12 @@ LOADER_API int loader_register(const char *name, loader_register_invoke invoke, LOADER_API int loader_register_impl(void *impl, void *handle, const char *name, loader_register_invoke invoke, type_id return_type, size_t arg_size, type_id args_type_id[]); +LOADER_API void loader_detour(detour d); + +LOADER_API detour_handle loader_hook(const loader_tag tag, const char *library, int (*load_cb)(detour, detour_handle)); + +LOADER_API detour_handle loader_hook_impl(void *impl, const char *library, int (*load_cb)(detour, detour_handle)); + LOADER_API const char *loader_library_path(void); LOADER_API int loader_execution_path(const loader_tag tag, const loader_path path); @@ -75,13 +75,15 @@ LOADER_API int loader_load_from_configuration(const loader_path path, void **han LOADER_API loader_impl loader_get_impl(const loader_tag tag); -LOADER_API loader_data loader_get(const char *name); +LOADER_API value loader_get(const char *name); LOADER_API void *loader_get_handle(const loader_tag tag, const char *name); -LOADER_API void loader_set_options(const loader_tag tag, void *options); +LOADER_API int loader_set_options(const loader_tag tag, value options); + +LOADER_API value loader_get_options(const loader_tag tag); -LOADER_API void *loader_get_options(const loader_tag tag); +LOADER_API value loader_get_option(const loader_tag tag, const char *field); LOADER_API int loader_handle_initialize(loader_impl impl, const loader_path name, void **handle_ptr); @@ -89,7 +91,7 @@ LOADER_API const char *loader_handle_id(void *handle); LOADER_API void *loader_handle_export(void *handle); -LOADER_API loader_data loader_handle_get(void *handle, const char *name); +LOADER_API value loader_handle_get(void *handle, const char *name); LOADER_API int loader_handle_populate(void *handle_dest, void *handle_src); diff --git a/source/loader/include/loader/loader_handle.h b/source/loader/include/loader/loader_handle.h index 68fc94ae7c..1d388fff94 100644 --- a/source/loader/include/loader/loader_handle.h +++ b/source/loader/include/loader/loader_handle.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loader/include/loader/loader_host.h b/source/loader/include/loader/loader_host.h index ce41c3c3d0..cc740a299b 100644 --- a/source/loader/include/loader/loader_host.h +++ b/source/loader/include/loader/loader_host.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,8 @@ extern "C" { LOADER_API plugin loader_host_initialize(void); +LOADER_API plugin loader_host_get(void); + LOADER_API int loader_host_register(loader_impl host, context ctx, const char *name, loader_register_invoke invoke, function *func, type_id return_type, size_t arg_size, type_id args_type_id[]); #ifdef __cplusplus diff --git a/source/loader/include/loader/loader_impl.h b/source/loader/include/loader/loader_impl.h index c6c8826d6d..0fb27961a1 100644 --- a/source/loader/include/loader/loader_impl.h +++ b/source/loader/include/loader/loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,18 +29,30 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif /* -- Methods -- */ +LOADER_NO_EXPORT int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl); + LOADER_API int loader_impl_is_initialized(loader_impl impl); LOADER_API loader_impl loader_impl_create(const loader_tag tag); LOADER_API loader_impl loader_impl_create_host(const loader_tag tag); +LOADER_API int loader_impl_dependencies(loader_impl impl, detour d, const loader_tag tag); + +LOADER_API int loader_impl_link(plugin p, loader_impl impl); + +LOADER_API dynlink loader_impl_dependency(loader_impl impl, const char *library); + +LOADER_API detour_handle loader_impl_detour(loader_impl impl, const char *library, int (*load_cb)(detour, detour_handle)); + LOADER_API void loader_impl_attach(loader_impl impl, plugin p); LOADER_API plugin loader_impl_plugin(loader_impl impl); @@ -65,9 +77,13 @@ LOADER_API int loader_impl_load_from_package(plugin_manager manager, plugin p, l LOADER_API void *loader_impl_get_handle(loader_impl impl, const char *name); -LOADER_API void loader_impl_set_options(loader_impl impl, void *options); +LOADER_API void loader_impl_set_options(loader_impl impl, value options); + +LOADER_API value loader_impl_get_options(loader_impl impl); + +LOADER_API value loader_impl_get_option(loader_impl impl, const char *field); -LOADER_API void *loader_impl_get_options(loader_impl impl); +LOADER_API int loader_impl_get_option_host(loader_impl impl); LOADER_API int loader_impl_handle_initialize(plugin_manager manager, plugin p, loader_impl impl, const loader_path name, void **handle_ptr); diff --git a/source/loader/include/loader/loader_impl_data.h b/source/loader/include/loader/loader_impl_data.h index 8148886762..d999280323 100644 --- a/source/loader/include/loader/loader_impl_data.h +++ b/source/loader/include/loader/loader_impl_data.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loader/include/loader/loader_impl_interface.h b/source/loader/include/loader/loader_impl_interface.h index 7033b2d5cd..7fa5e1b0cf 100644 --- a/source/loader/include/loader/loader_impl_interface.h +++ b/source/loader/include/loader/loader_impl_interface.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,8 +35,6 @@ extern "C" { #endif -#include - struct loader_impl_type; typedef struct loader_impl_type *loader_impl; diff --git a/source/loader/include/loader/loader_manager_impl.h b/source/loader/include/loader/loader_manager_impl.h index 4e1253c125..3e9c4d82c0 100644 --- a/source/loader/include/loader/loader_manager_impl.h +++ b/source/loader/include/loader/loader_manager_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,7 @@ struct loader_manager_impl_type uint64_t init_thread_id; /* Stores the thread id of the thread that initialized metacall */ vector script_paths; /* Vector of search path for the scripts */ set destroy_map; /* Tracks the list of destroyed runtimes during destruction of the manager (loader_impl -> NULL) */ + detour d; /* Stores the detour manager that is being used for hooking */ }; /* -- Type Definitions -- */ diff --git a/source/loader/include/loader/loader_naming.h b/source/loader/include/loader/loader_naming.h index e49b528076..b04627f784 100644 --- a/source/loader/include/loader/loader_naming.h +++ b/source/loader/include/loader/loader_naming.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loader/source/loader.c b/source/loader/source/loader.c index 82bb7d5a4f..c01c2c1929 100644 --- a/source/loader/source/loader.c +++ b/source/loader/source/loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,6 @@ #include -#include - #include #include @@ -48,26 +46,6 @@ #define LOADER_LIBRARY_PATH "LOADER_LIBRARY_PATH" #define LOADER_LIBRARY_DEFAULT_PATH "loaders" -/* -- Member Data -- */ - -struct loader_metadata_cb_iterator_type -{ - size_t iterator; - value *values; -}; - -struct loader_get_cb_iterator_type -{ - const char *name; - value obj; /* scope_object */ -}; - -/* -- Type Definitions -- */ - -typedef struct loader_get_cb_iterator_type *loader_get_cb_iterator; - -typedef struct loader_metadata_cb_iterator_type *loader_metadata_cb_iterator; - /* -- Private Methods -- */ static void loader_initialization_debug(void); @@ -76,9 +54,7 @@ static void loader_initialization_register_plugin(plugin p); static plugin loader_get_impl_plugin(const loader_tag tag); -static int loader_get_cb_iterate(plugin_manager manager, plugin p, void *data); - -static int loader_metadata_cb_iterate(plugin_manager manager, plugin p, void *data); +static plugin loader_get_impl_plugin_options(const loader_tag tag, value options); /* -- Member Data -- */ @@ -134,6 +110,9 @@ int loader_initialize(void) /* Insert into destruction list */ loader_initialization_register_plugin(manager_impl->host); + /* Initialize detours */ + manager_impl->d = NULL; + /* TODO: Disable logs here until log is completely thread safe and async signal safe */ /* log_write("metacall", LOG_LEVEL_DEBUG, "Loader host initialized"); */ @@ -225,22 +204,58 @@ int loader_register_impl(void *impl, void *handle, const char *name, loader_regi return loader_host_register((loader_impl)impl, loader_impl_handle_context(handle), name, invoke, NULL, return_type, arg_size, args_type_id); } +void loader_detour(detour d) +{ + loader_manager_impl manager_impl = plugin_manager_impl_type(&loader_manager, loader_manager_impl); + + manager_impl->d = d; +} + +detour_handle loader_hook(const loader_tag tag, const char *library, int (*load_cb)(detour, detour_handle)) +{ + return loader_impl_detour(loader_get_impl(tag), library, load_cb); +} + +detour_handle loader_hook_impl(void *impl, const char *library, int (*load_cb)(detour, detour_handle)) +{ + return loader_impl_detour((loader_impl)impl, library, load_cb); +} + plugin loader_get_impl_plugin(const loader_tag tag) +{ + return loader_get_impl_plugin_options(tag, NULL); +} + +plugin loader_get_impl_plugin_options(const loader_tag tag, value options) { plugin p = plugin_manager_get(&loader_manager, tag); + loader_impl impl; + if (p != NULL) { return p; } - loader_impl impl = loader_impl_create(tag); + impl = loader_impl_create(tag); if (impl == NULL) { + /* Destroy options on error */ + value_type_destroy(options); goto loader_create_error; } + /* Define the options */ + loader_impl_set_options(impl, options); + + /* Dynamic link loader dependencies if it is not host */ + if (loader_impl_dependencies(impl, plugin_manager_impl_type(&loader_manager, loader_manager_impl)->d, tag) != 0) + { + goto plugin_manager_create_error; + } + + /* Dynamic link the loader */ p = plugin_manager_create(&loader_manager, tag, impl, &loader_impl_destroy_dtor); if (p == NULL) @@ -248,9 +263,30 @@ plugin loader_get_impl_plugin(const loader_tag tag) goto plugin_manager_create_error; } + /* If it is host, link the loader symbols to the host (either the executable or a library) */ + if (loader_impl_link(p, impl) != 0) + { + goto plugin_manager_create_error; + } + /* Store in the loader implementation the reference to the plugin which belongs to */ loader_impl_attach(impl, p); + /* Check if it is host, initialize it and set it as host */ + if (options != NULL && loader_impl_get_option_host(impl) == 1) + { + loader_manager_impl manager_impl; + + if (loader_impl_initialize(&loader_manager, p, plugin_impl_type(p, loader_impl)) != 0) + { + goto plugin_manager_create_error; + } + + manager_impl = plugin_manager_impl_type(&loader_manager, loader_manager_impl); + + manager_impl->host = p; + } + /* TODO: Disable logs here until log is completely thread safe and async signal safe */ /* log_write("metacall", LOG_LEVEL_DEBUG, "Created loader (%s) implementation <%p>", tag, (void *)impl); */ @@ -502,35 +538,25 @@ int loader_load_from_configuration(const loader_path path, void **handle, void * return 0; } -int loader_get_cb_iterate(plugin_manager manager, plugin p, void *data) +value loader_get(const char *name) { - loader_impl impl = plugin_impl_type(p, loader_impl); - loader_get_cb_iterator get_iterator = data; - - (void)manager; - - get_iterator->obj = loader_impl_get_value(impl, get_iterator->name); + struct set_iterator_type it; - if (get_iterator->obj != NULL) + for (set_iterator_begin(&it, loader_manager.plugins); set_iterator_end(&it) != 0; set_iterator_next(&it)) { - /* TODO: Disable logs here until log is completely thread safe and async signal safe */ - /* log_write("metacall", LOG_LEVEL_DEBUG, "Loader (%s) get value: %s <%p>", plugin_name(p), get_iterator->name, (void *)get_iterator->obj); */ - return 1; - } + plugin p = set_iterator_value(&it); - return 0; -} + loader_impl impl = plugin_impl_type(p, loader_impl); -loader_data loader_get(const char *name) -{ - struct loader_get_cb_iterator_type get_iterator; + value scope_object = loader_impl_get_value(impl, name); - get_iterator.name = name; - get_iterator.obj = NULL; - - plugin_manager_iterate(&loader_manager, &loader_get_cb_iterate, (void *)&get_iterator); + if (scope_object != NULL) + { + return scope_object; + } + } - return (loader_data)get_iterator.obj; + return NULL; } void *loader_get_handle(const loader_tag tag, const char *name) @@ -540,20 +566,27 @@ void *loader_get_handle(const loader_tag tag, const char *name) return loader_impl_get_handle(plugin_impl_type(p, loader_impl), name); } -void loader_set_options(const loader_tag tag, void *options) +int loader_set_options(const loader_tag tag, value options) { - plugin p = loader_get_impl_plugin(tag); + plugin p = loader_get_impl_plugin_options(tag, options); - loader_impl_set_options(plugin_impl_type(p, loader_impl), options); + return (p == NULL); } -void *loader_get_options(const loader_tag tag) +value loader_get_options(const loader_tag tag) { plugin p = loader_get_impl_plugin(tag); return loader_impl_get_options(plugin_impl_type(p, loader_impl)); } +value loader_get_option(const loader_tag tag, const char *field) +{ + plugin p = loader_get_impl_plugin(tag); + + return loader_impl_get_option(plugin_impl_type(p, loader_impl), field); +} + int loader_handle_initialize(loader_impl impl, const loader_path name, void **handle_ptr) { if (loader_initialize() == 1) @@ -597,7 +630,7 @@ value loader_handle_export(void *handle) return loader_impl_handle_export(handle); } -loader_data loader_handle_get(void *handle, const char *name) +value loader_handle_get(void *handle, const char *name) { if (handle != NULL) { @@ -645,37 +678,32 @@ value loader_metadata_impl(plugin p, loader_impl impl) return v; } -int loader_metadata_cb_iterate(plugin_manager manager, plugin p, void *data) -{ - loader_impl impl = plugin_impl_type(p, loader_impl); - loader_metadata_cb_iterator metadata_iterator = data; - - (void)manager; - - metadata_iterator->values[metadata_iterator->iterator] = loader_metadata_impl(p, impl); - - if (metadata_iterator->values[metadata_iterator->iterator] != NULL) - { - ++metadata_iterator->iterator; - } - - return 0; -} - value loader_metadata(void) { - struct loader_metadata_cb_iterator_type metadata_iterator; - value v = value_create_map(NULL, plugin_manager_size(&loader_manager)); + value *values, v = value_create_map(NULL, plugin_manager_size(&loader_manager)); + struct set_iterator_type it; + size_t values_it; if (v == NULL) { return NULL; } - metadata_iterator.iterator = 0; - metadata_iterator.values = value_to_map(v); + values = value_to_map(v); + + for (set_iterator_begin(&it, loader_manager.plugins), values_it = 0; set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + plugin p = set_iterator_value(&it); - plugin_manager_iterate(&loader_manager, &loader_metadata_cb_iterate, (void *)&metadata_iterator); + loader_impl impl = plugin_impl_type(p, loader_impl); + + values[values_it] = loader_metadata_impl(p, impl); + + if (values[values_it] != NULL) + { + ++values_it; + } + } return v; } @@ -740,7 +768,7 @@ void loader_unload_children(loader_impl impl) * the loader has been unloaded, and the function interface will point to an unloaded * plugin, generating a segmentation fault. All the plugins will be unloaded on plugin_manager_destroy. */ - plugin_destroy_delayed(order->p); + plugin_destructor(order->p); /* Mark loader as destroyed (prevents access to already freed memory and defines what loaders are destroyed) */ loader_manager_impl_set_destroyed(manager_impl, destroyed_impl); @@ -790,15 +818,19 @@ void loader_destroy(void) loader_unload_children(NULL); /* The host is the first loader, it must be destroyed at the end */ - if (manager_impl->host != NULL) + if (manager_impl->host == loader_host_get()) { if (plugin_manager_clear(&loader_manager, manager_impl->host) != 0) { log_write("metacall", LOG_LEVEL_ERROR, "Failed to clear host loader"); } - - manager_impl->host = NULL; } + else + { + plugin_destroyed(manager_impl->host); + } + + manager_impl->host = NULL; } plugin_manager_destroy(&loader_manager); @@ -810,7 +842,7 @@ const char *loader_print_info(void) { static const char loader_info[] = "Loader Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loader/source/loader_host.c b/source/loader/source/loader_host.c index 28f9ebf72d..0ac16440f3 100644 --- a/source/loader/source/loader_host.c +++ b/source/loader/source/loader_host.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ union loader_host_invoke_cast static value function_host_interface_invoke(function func, function_impl func_impl, function_args args, size_t size); -static function_return function_host_interface_await(function func, function_impl impl, function_args args, size_t size, function_resolve_callback resolve_callback, function_reject_callback reject_callback, void *context); +static function_return function_host_interface_await(function func, function_impl impl, function_args args, size_t size, function_resolve_callback resolve_callback, function_reject_callback reject_callback, void *ctx); static function_interface function_host_singleton(void); @@ -52,6 +52,10 @@ static void loader_host_destroy_dtor(plugin p); static void loader_host_destroy(loader_impl host); +/* -- Private Member Data -- */ + +static plugin loader_host_plugin = NULL; + /* -- Methods -- */ function_return function_host_interface_invoke(function func, function_impl func_impl, function_args args, size_t size) @@ -64,7 +68,7 @@ function_return function_host_interface_invoke(function func, function_impl func return invoke_cast.fn(size, args, data); } -function_return function_host_interface_await(function func, function_impl impl, function_args args, size_t size, function_resolve_callback resolve_callback, function_reject_callback reject_callback, void *context) +function_return function_host_interface_await(function func, function_impl impl, function_args args, size_t size, function_resolve_callback resolve_callback, function_reject_callback reject_callback, void *ctx) { /* TODO */ @@ -74,7 +78,7 @@ function_return function_host_interface_await(function func, function_impl impl, (void)size; (void)resolve_callback; (void)reject_callback; - (void)context; + (void)ctx; return NULL; } @@ -139,12 +143,19 @@ plugin loader_host_initialize(void) goto error; } + loader_host_plugin = p; + return p; error: loader_host_destroy(host); return NULL; } +plugin loader_host_get(void) +{ + return loader_host_plugin; +} + int loader_host_register(loader_impl host, context ctx, const char *name, loader_register_invoke invoke, function *func, type_id return_type, size_t arg_size, type_id args_type_id[]) { void **invoke_ptr = (void *)&invoke; diff --git a/source/loader/source/loader_impl.c b/source/loader/source/loader_impl.c index c6ccf3297a..ac35595f53 100644 --- a/source/loader/source/loader_impl.c +++ b/source/loader/source/loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,9 @@ #include #include +#include + +#include #include #include @@ -63,18 +66,10 @@ struct loader_handle_impl_type; -struct loader_impl_metadata_cb_iterator_type; - -struct loader_impl_handle_register_cb_iterator_type; - /* -- Type Definitions -- */ typedef struct loader_handle_impl_type *loader_handle_impl; -typedef struct loader_impl_metadata_cb_iterator_type *loader_impl_metadata_cb_iterator; - -typedef struct loader_impl_handle_register_cb_iterator_type *loader_impl_handle_register_cb_iterator; - /* -- Member Data -- */ struct loader_impl_type @@ -87,8 +82,12 @@ struct loader_impl_type loader_impl_data data; /* Derived metadata provided by the loader, usually contains the data of the VM, Interpreter or JIT */ context ctx; /* Contains the objects, classes and functions loaded in the global scope of each loader */ set type_info_map; /* Stores a set indexed by type name of all of the types existing in the loader (global scope (TODO: may need refactor per handle)) */ - void *options; /* Additional initialization options passed in the initialize phase */ + value options; /* Additional initialization options passed in the initialize phase */ set exec_path_map; /* Set of execution paths passed by the end user */ + configuration config; /* Reference to the loader configuration, it contains execution_paths, dependencies and additional info */ + set library_map; /* List of handles (dynlink) to the dependencies of the loader and the loader itself */ + detour d; /* Reference to the detour which was used for hooking the loader or its dependencies */ + set detour_map; /* List of detour handles (detour_handle) to the dependencies of the loader and the loader itself */ }; struct loader_handle_impl_type @@ -103,34 +102,30 @@ struct loader_handle_impl_type vector populated_handles; /* Vector containing all the references to which this handle has been populated into, it is necessary for detach the symbols when destroying (used in load_from_* when passing an input parameter) */ }; -struct loader_impl_handle_register_cb_iterator_type -{ - context handle_ctx; - char *duplicated_key; -}; - -struct loader_impl_metadata_cb_iterator_type -{ - size_t iterator; - value *values; -}; - /* -- Private Methods -- */ static loader_impl loader_impl_allocate(const loader_tag tag); -static configuration loader_impl_initialize_configuration(plugin p); +static void loader_impl_configuration_execution_paths(loader_impl_interface iface, loader_impl impl); -static int loader_impl_initialize_registered(plugin_manager manager, plugin p); +static int loader_impl_dependencies_self_list(const char *library, void *data); + +static int loader_impl_dependencies_self_find(loader_impl impl, const char *key_str, vector dependencies_self); + +static int loader_impl_dependencies_load(loader_impl impl, const char *key_str, value *paths_array, size_t paths_size); -static int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl); +#if defined(WIN32) || defined(_WIN32) +static void loader_impl_dependencies_search_paths(loader_impl impl, const loader_tag tag); +#endif + +static configuration loader_impl_initialize_configuration(const loader_tag tag); + +static int loader_impl_initialize_registered(plugin_manager manager, plugin p); static loader_handle_impl loader_impl_load_handle(loader_impl impl, loader_impl_interface iface, loader_handle module, const char *path, size_t size); static int loader_impl_handle_init(loader_impl impl, const char *path, loader_handle_impl handle_impl, void **handle_ptr, int populated); -static int loader_impl_handle_register_cb_iterate(plugin_manager manager, plugin p, void *data); - static int loader_impl_handle_register(plugin_manager manager, loader_impl impl, const char *path, loader_handle_impl handle_impl, void **handle_ptr); static size_t loader_impl_handle_name(plugin_manager manager, const loader_path path, loader_path result); @@ -143,12 +138,8 @@ static value loader_impl_metadata_handle_context(loader_handle_impl handle_impl) static value loader_impl_metadata_handle(loader_handle_impl handle_impl); -static int loader_impl_metadata_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - static void loader_impl_destroy_handle(loader_handle_impl handle_impl); -static int loader_impl_destroy_type_map_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - /* -- Private Member Data -- */ static const char loader_handle_impl_magic_alloc[] = "loader_handle_impl_magic_alloc"; @@ -209,8 +200,26 @@ loader_impl loader_impl_allocate(const loader_tag tag) goto alloc_exec_path_map_error; } + impl->library_map = set_create(&hash_callback_str, &comparable_callback_str); + + if (impl->library_map == NULL) + { + goto alloc_library_map_error; + } + + impl->detour_map = set_create(&hash_callback_str, &comparable_callback_str); + + if (impl->detour_map == NULL) + { + goto alloc_detour_map_error; + } + return impl; +alloc_detour_map_error: + set_destroy(impl->library_map); +alloc_library_map_error: + set_destroy(impl->exec_path_map); alloc_exec_path_map_error: context_destroy(impl->ctx); alloc_ctx_error: @@ -260,50 +269,378 @@ plugin loader_impl_plugin(loader_impl impl) return NULL; } -void loader_impl_configuration(loader_impl_interface iface, loader_impl impl, configuration config) +void loader_impl_configuration_execution_paths(loader_impl_interface iface, loader_impl impl) { - value execution_paths_value = configuration_value_type(config, "execution_paths", TYPE_ARRAY); + value execution_paths_value = configuration_value_type(impl->config, "execution_paths", TYPE_ARRAY); if (execution_paths_value != NULL) { size_t size = value_type_count(execution_paths_value); value *execution_paths_array = value_to_array(execution_paths_value); + size_t iterator; + + for (iterator = 0; iterator < size; ++iterator) + { + if (value_type_id(execution_paths_array[iterator]) == TYPE_STRING) + { + loader_path execution_path; + + configuration_object_child_path(impl->config, execution_paths_array[iterator], 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)); + } + } + } + } +} + +int loader_impl_dependencies_self_list(const char *library, void *data) +{ + vector dependencies_self = (vector)data; - if (execution_paths_array != NULL) + vector_push_back_empty(dependencies_self); + + strncpy(vector_back(dependencies_self), library, strnlen(library, PORTABILITY_PATH_SIZE) + 1); + + return 0; +} + +int loader_impl_dependencies_self_find(loader_impl impl, const char *key_str, vector dependencies_self) +{ + size_t iterator, size = vector_size(dependencies_self); + char library_self_name[PORTABILITY_PATH_SIZE]; + dynlink handle; + + /* Try to load it from the dependencies of the executable */ + for (iterator = 0; iterator < size; ++iterator) + { + const char *library_self = vector_at(dependencies_self, iterator); + + /* Get the name of the library */ + portability_path_get_fullname(library_self, strnlen(library_self, PORTABILITY_PATH_SIZE) + 1, library_self_name, PORTABILITY_PATH_SIZE); + + /* Try to find the dependency name in the library */ + if (strstr(library_self_name, key_str) != NULL) + { + handle = dynlink_load_absolute(library_self, DYNLINK_FLAGS_BIND_LAZY | DYNLINK_FLAGS_BIND_GLOBAL); + + goto dependencies_map_insert; + } + } + + /* If it is not found in the dependencies, it is linked statically to the executable, load it */ + handle = dynlink_load_self(DYNLINK_FLAGS_BIND_LAZY | DYNLINK_FLAGS_BIND_GLOBAL); + +dependencies_map_insert: + + if (handle != NULL && set_insert(impl->library_map, (const set_key)key_str, (set_value)handle) == 0) + { + return 0; + } + + dynlink_unload(handle); + + return 1; +} + +int loader_impl_dependencies_load(loader_impl impl, const char *key_str, value *paths_array, size_t paths_size) +{ + size_t iterator; + + for (iterator = 0; iterator < paths_size; ++iterator) + { + if (value_type_id(paths_array[iterator]) == TYPE_STRING) { - size_t iterator; + const char *library_path = value_to_string(paths_array[iterator]); - for (iterator = 0; iterator < size; ++iterator) + if (library_path != NULL) { - if (execution_paths_array[iterator] != NULL) + dynlink handle = dynlink_load_absolute(library_path, DYNLINK_FLAGS_BIND_LAZY | DYNLINK_FLAGS_BIND_GLOBAL); + + if (handle != NULL && set_insert(impl->library_map, (const set_key)key_str, (set_value)handle) == 0) { - const char *str = value_to_string(execution_paths_array[iterator]); - size_t str_size = value_type_size(execution_paths_array[iterator]); + return 0; + } - if (str != NULL) + dynlink_unload(handle); + } + } + } + + return 1; +} + +#if defined(WIN32) || defined(_WIN32) +void loader_impl_dependencies_search_paths(loader_impl impl, const loader_tag tag) +{ + /* Search paths have the following format and are only implemented for Windows: + { + "search_paths": ["C:\Program Files\ruby\bin\ruby_builtin_dlls"] + } + */ + value search_paths_value = configuration_value_type(impl->config, "search_paths", TYPE_ARRAY); + + /* Check if the loader has search paths and initialize them */ + if (search_paths_value != NULL) + { + size_t size = value_type_count(search_paths_value); + value *search_paths_array = value_to_array(search_paths_value); + size_t iterator; + + for (iterator = 0; iterator < size; ++iterator) + { + if (value_type_id(search_paths_array[iterator]) == TYPE_STRING) + { + const char *key_str = value_to_string(search_paths_array[iterator]); + + if (SetDllDirectoryA(key_str) == FALSE) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to register the DLL directory %s in loader '%s'; dependencies with other dependant DLLs may fail to load", key_str, tag); + } + } + } + } +} +#endif + +int loader_impl_dependencies(loader_impl impl, detour d, const loader_tag tag) +{ + /* Dependencies have the following format: + { + "dependencies": { + "node": ["/usr/lib/x86_64-linux-gnu/libnode.so.72"] + } + } + */ + value dependencies_value = configuration_value_type(impl->config, "dependencies", TYPE_MAP); + + /* The algorithm works in the following way: + 1) If current loader is the host: + - Take the dependency name and try to find if it is already + loaded as a library in the current process, for example: + + "dependencies": { + "node": ["/usr/lib/x86_64-linux-gnu/libnode.so.72"] + } + + Will search for all libraries, looking for the library name + with the following substring (lib)node, so if we find: + + "/usr/lib/x86_64-linux-gnu/libnode.so.108" + + It will test against libnode.so.108 the substring (lib)node. + + - If it has not been found, then get the handle of the current process. + + 2) Otherwise, the current loader is not the host: + - Iterate the dependencies and if they are properly loaded, index + them by name in the dependency map, for example: + + [ Key ] => [ Value ] + "node" => "/usr/lib/x86_64-linux-gnu/libnode.so.72" + + The value in this case will be the library loaded, instead of the full path. + */ + + /* Initialize the loader detour */ + impl->d = d; + +#if defined(WIN32) || defined(_WIN32) + loader_impl_dependencies_search_paths(impl, tag); +#endif + + /* Check if the loader has dependencies and load them */ + if (dependencies_value != NULL) + { + size_t size = value_type_count(dependencies_value); + value *dependencies_map = value_to_map(dependencies_value); + vector dependencies_self = NULL; + size_t iterator; + const int host = loader_impl_get_option_host(impl); + + /* In case of host, get all loaded dependencies into an array */ + if (host == 1) + { + dependencies_self = vector_create(sizeof(char) * PORTABILITY_PATH_SIZE); + + if (dependencies_self == NULL) + { + return 1; + } + + if (portability_library_path_list(&loader_impl_dependencies_self_list, (void *)dependencies_self) != 0) + { + vector_destroy(dependencies_self); + return 1; + } + } + + /* Iterate through the dependencies */ + for (iterator = 0; iterator < size; ++iterator) + { + if (value_type_id(dependencies_map[iterator]) == TYPE_ARRAY) + { + value *library_tuple = value_to_array(dependencies_map[iterator]); + + if (value_type_id(library_tuple[0]) == TYPE_STRING) + { + const char *key_str = value_to_string(library_tuple[0]); + + if (host == 0) { - loader_path execution_path; + /* If the loader is not the host, iterate through all dependencies and load them */ + if (value_type_id(library_tuple[1]) == TYPE_ARRAY) + { + value *paths_array = value_to_array(library_tuple[1]); + size_t paths_size = value_type_count(library_tuple[1]); - strncpy(execution_path, str, str_size > LOADER_PATH_SIZE ? LOADER_PATH_SIZE : str_size); + if (loader_impl_dependencies_load(impl, key_str, paths_array, paths_size) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load dependency '%s' from loader '%s' configuration", key_str, tag); + return 1; + } + } + } + else + { + /* Otherwise try to find if the library is already loaded, and if not, load the process */ + if (loader_impl_dependencies_self_find(impl, key_str, dependencies_self) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to load dependency '%s' from loader '%s' as a host", key_str, tag); + vector_destroy(dependencies_self); + return 1; + } + } + } + } + } + + vector_destroy(dependencies_self); + } - iface->execution_path(impl, execution_path); + return 0; +} + +int loader_impl_link(plugin p, loader_impl impl) +{ + plugin_descriptor desc = plugin_desc(p); + + /* On Linux and MacOS, if the symbols are exported, + the linker when loading the library automatically resolves the symbols + so there is no need for doing the link manually, in Windows meanwhile + we link the dependency with delay load linking. Before we execute anything, + we should relink all the symbols to the host. + */ +#if defined(WIN32) || defined(_WIN32) + if (loader_impl_get_option_host(impl) == 1) + { + /* Replace loader symbols by the dependency (aka the already loaded + library if the host is linked dynamically, or the executable if it is + linked statically) */ + detour_handle loader_handle = detour_load_handle(impl->d, desc->handle); + + if (loader_handle != NULL) + { + unsigned int position = 0; + const char *name = NULL; + void (**addr)(void) = NULL; + + while (detour_enumerate(impl->d, loader_handle, &position, &name, &addr) == 0) + { + /* Iterate through all library handles in the library map */ + struct set_iterator_type it; + + for (set_iterator_begin(&it, impl->library_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + dynlink library_handle = set_iterator_value(&it); + + /* Try to find the symbols in the dependencies, do not use the + loader dynlink handle for this, it is included in the library map */ + if (library_handle != NULL && library_handle != desc->handle) + { + dynlink_symbol_addr symbol = NULL; + + if (dynlink_symbol(library_handle, name, &symbol) == 0 && symbol != NULL) + { + if (detour_replace(impl->d, loader_handle, name, symbol, NULL) == 0) + { + /* Symbol successfully replaced */ + break; + } + } } } } + + detour_unload(impl->d, loader_handle); } } +#endif + + /* Store itself in the library map along with the dependencies */ + if (set_insert(impl->library_map, (set_key)desc->library_name, (set_value)desc->handle) != 0) + { + return 1; + } + + return 0; +} + +dynlink loader_impl_dependency(loader_impl impl, const char *library) +{ + dynlink library_handle = set_get(impl->library_map, (const set_key)library); + + return library_handle; +} + +detour_handle loader_impl_detour(loader_impl impl, const char *library, int (*load_cb)(detour, detour_handle)) +{ + detour_handle handle = set_get(impl->detour_map, (const set_key)library); + + if (handle == NULL) + { + dynlink library_handle = set_get(impl->library_map, (const set_key)library); + + if (library_handle == NULL) + { + return NULL; + } + + handle = detour_load_handle(impl->d, library_handle); + + if (handle == NULL) + { + return NULL; + } + + if (load_cb(impl->d, handle) != 0) + { + detour_unload(impl->d, handle); + return NULL; + } + + if (set_insert(impl->detour_map, (set_key)library, handle) != 0) + { + detour_unload(impl->d, handle); + return NULL; + } + } + + return handle; } -configuration loader_impl_initialize_configuration(plugin p) +configuration loader_impl_initialize_configuration(const loader_tag tag) { static const char configuration_key_suffix[] = "_loader"; #define CONFIGURATION_KEY_SIZE ((size_t)sizeof(configuration_key_suffix) + LOADER_TAG_SIZE - 1) char configuration_key[CONFIGURATION_KEY_SIZE]; /* Retrieve the configuration key: _loader */ - size_t tag_size = strnlen(plugin_name(p), LOADER_TAG_SIZE) + 1; + size_t tag_size = strnlen(tag, LOADER_TAG_SIZE) + 1; - strncpy(configuration_key, plugin_name(p), tag_size); + strncpy(configuration_key, tag, tag_size); strncat(configuration_key, configuration_key_suffix, CONFIGURATION_KEY_SIZE - tag_size); #undef CONFIGURATION_KEY_SIZE @@ -333,7 +670,6 @@ int loader_impl_initialize_registered(plugin_manager manager, plugin p) int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl) { static const char loader_library_path[] = "loader_library_path"; - configuration config; value loader_library_path_value = NULL; char *library_path = NULL; vector script_paths, paths; @@ -343,9 +679,6 @@ int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl) return 0; } - /* Get the configuration of the loader */ - config = loader_impl_initialize_configuration(p); - /* Retrieve the library path */ library_path = plugin_manager_library_path(manager); @@ -357,19 +690,19 @@ int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl) */ /* Check if the configuration has a custom loader_library_path, otherwise set it up */ - if (config != NULL && configuration_value_type(config, loader_library_path, TYPE_STRING) == NULL) + if (impl->config != NULL && configuration_value_type(impl->config, loader_library_path, TYPE_STRING) == NULL) { loader_library_path_value = value_create_string(library_path, strnlen(library_path, LOADER_PATH_SIZE)); - configuration_define(config, loader_library_path, loader_library_path_value); + configuration_define(impl->config, loader_library_path, loader_library_path_value); } /* Call to the loader initialize method */ - impl->data = loader_iface(p)->initialize(impl, config); + impl->data = loader_iface(p)->initialize(impl, impl->config); /* Undefine the library path field from config */ - if (config != NULL && loader_library_path_value != NULL) + if (impl->config != NULL && loader_library_path_value != NULL) { - configuration_undefine(config, loader_library_path); + configuration_undefine(impl->config, loader_library_path); value_type_destroy(loader_library_path_value); } @@ -392,9 +725,9 @@ int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl) impl->init = 0; - if (config != NULL) + if (impl->config != NULL) { - loader_impl_configuration(loader_iface(p), impl, config); + loader_impl_configuration_execution_paths(loader_iface(p), impl); } /* The scripts path priority order is the following: @@ -404,7 +737,7 @@ int loader_impl_initialize(plugin_manager manager, plugin p, loader_impl impl) */ /* Load the library path as execution path */ - loader_library_path_value = configuration_value_type(config, loader_library_path, TYPE_STRING); + loader_library_path_value = configuration_value_type(impl->config, loader_library_path, TYPE_STRING); if (loader_library_path_value != NULL) { @@ -472,6 +805,9 @@ loader_impl loader_impl_create(const loader_tag tag) impl->init = 1; impl->options = NULL; + /* Get the configuration of the loader */ + impl->config = loader_impl_initialize_configuration(tag); + return impl; } @@ -708,36 +1044,29 @@ int loader_impl_handle_init(loader_impl impl, const char *path, loader_handle_im return result; } -int loader_impl_handle_register_cb_iterate(plugin_manager manager, plugin p, void *data) -{ - loader_impl impl = plugin_impl_type(p, loader_impl); - loader_impl_handle_register_cb_iterator iterator = (loader_impl_handle_register_cb_iterator)data; - - (void)manager; - - return (context_contains(impl->ctx, iterator->handle_ctx, &iterator->duplicated_key) == 0); -} - int loader_impl_handle_register(plugin_manager manager, loader_impl impl, const char *path, loader_handle_impl handle_impl, void **handle_ptr) { /* If there's no handle input/output pointer passed as input parameter, then propagate the handle symbols to the loader context */ if (handle_ptr == NULL) { - /* This case handles the global scope (shared scope between all loaders, there is no out reference to a handle) */ - struct loader_impl_handle_register_cb_iterator_type iterator; + struct set_iterator_type it; - iterator.handle_ctx = handle_impl->ctx; - iterator.duplicated_key = NULL; - - /* This checks if there are duplicated keys between all loaders and the current handle context */ - plugin_manager_iterate(manager, &loader_impl_handle_register_cb_iterate, &iterator); - - if (iterator.duplicated_key != NULL) + /* This case handles the global scope (shared scope between all loaders, there is no out reference to a handle) */ + for (set_iterator_begin(&it, manager->plugins); set_iterator_end(&it) != 0; set_iterator_next(&it)) { - log_write("metacall", LOG_LEVEL_ERROR, "Duplicated symbol found named '%s' already defined in the global scope by handle: %s", iterator.duplicated_key, path); - return 1; + plugin p = set_iterator_value(&it); + loader_impl other_impl = plugin_impl_type(p, loader_impl); + char *duplicated_key = NULL; + + /* This checks if there are duplicated keys between all loaders and the current handle context */ + if (context_contains(other_impl->ctx, handle_impl->ctx, &duplicated_key) == 0 && duplicated_key != NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Duplicated symbol found named '%s' already defined in the global scope by handle: %s", duplicated_key, path); + return 1; + } } - else if (context_append(impl->ctx, handle_impl->ctx) == 0) + + if (context_append(impl->ctx, handle_impl->ctx) == 0) { return loader_impl_handle_init(impl, path, handle_impl, handle_ptr, 0); } @@ -821,7 +1150,8 @@ int loader_impl_load_from_file(plugin_manager manager, plugin p, loader_impl imp { loader_handle handle; loader_path path; - size_t init_order; + size_t init_order = 0; + int init_order_not_initialized = !(handle_ptr != NULL && *handle_ptr != NULL); if (loader_impl_initialize(manager, p, impl) != 0) { @@ -835,9 +1165,12 @@ int loader_impl_load_from_file(plugin_manager manager, plugin p, loader_impl imp return 1; } - init_order = vector_size(impl->handle_impl_init_order); + if (init_order_not_initialized) + { + init_order = vector_size(impl->handle_impl_init_order); - vector_push_back_empty(impl->handle_impl_init_order); + vector_push_back_empty(impl->handle_impl_init_order); + } handle = iface->load_from_file(impl, paths, size); @@ -863,7 +1196,10 @@ int loader_impl_load_from_file(plugin_manager manager, plugin p, loader_impl imp { if (loader_impl_handle_register(manager, impl, path, handle_impl, handle_ptr) == 0) { - vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + if (init_order_not_initialized) + { + vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + } return 0; } @@ -875,7 +1211,10 @@ int loader_impl_load_from_file(plugin_manager manager, plugin p, loader_impl imp set_remove(impl->handle_impl_path_map, handle_impl->path); } + if (init_order_not_initialized) { + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ size_t iterator; for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) @@ -895,16 +1234,21 @@ int loader_impl_load_from_file(plugin_manager manager, plugin p, loader_impl imp } else { - size_t iterator; - - for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + if (init_order_not_initialized) { - loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ + size_t iterator; - loader_impl_destroy_handle(iterator_handle_impl); - } + for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + { + loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); - vector_pop_back(impl->handle_impl_init_order); + loader_impl_destroy_handle(iterator_handle_impl); + } + + vector_pop_back(impl->handle_impl_init_order); + } } } } @@ -947,7 +1291,8 @@ int loader_impl_load_from_memory(plugin_manager manager, plugin p, loader_impl i { loader_name name; loader_handle handle = NULL; - size_t init_order; + size_t init_order = 0; + int init_order_not_initialized = !(handle_ptr != NULL && *handle_ptr != NULL); if (loader_impl_initialize(manager, p, impl) != 0) { @@ -968,9 +1313,12 @@ int loader_impl_load_from_memory(plugin_manager manager, plugin p, loader_impl i return 1; } - init_order = vector_size(impl->handle_impl_init_order); + if (init_order_not_initialized) + { + init_order = vector_size(impl->handle_impl_init_order); - vector_push_back_empty(impl->handle_impl_init_order); + vector_push_back_empty(impl->handle_impl_init_order); + } handle = iface->load_from_memory(impl, name, buffer, size); @@ -993,7 +1341,10 @@ int loader_impl_load_from_memory(plugin_manager manager, plugin p, loader_impl i { if (loader_impl_handle_register(manager, impl, name, handle_impl, handle_ptr) == 0) { - vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + if (init_order_not_initialized) + { + vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + } return 0; } @@ -1005,7 +1356,10 @@ int loader_impl_load_from_memory(plugin_manager manager, plugin p, loader_impl i set_remove(impl->handle_impl_path_map, handle_impl->path); } + if (init_order_not_initialized) { + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ size_t iterator; for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) @@ -1025,16 +1379,21 @@ int loader_impl_load_from_memory(plugin_manager manager, plugin p, loader_impl i } else { - size_t iterator; - - for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + if (init_order_not_initialized) { - loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ + size_t iterator; - loader_impl_destroy_handle(iterator_handle_impl); - } + for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + { + loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); - vector_pop_back(impl->handle_impl_init_order); + loader_impl_destroy_handle(iterator_handle_impl); + } + + vector_pop_back(impl->handle_impl_init_order); + } } } } @@ -1048,7 +1407,8 @@ int loader_impl_load_from_package(plugin_manager manager, plugin p, loader_impl { loader_impl_interface iface = loader_iface(p); loader_path subpath; - size_t init_order; + size_t init_order = 0; + int init_order_not_initialized = !(handle_ptr != NULL && *handle_ptr != NULL); if (iface != NULL && loader_impl_handle_name(manager, path, subpath) > 1) { @@ -1066,9 +1426,12 @@ int loader_impl_load_from_package(plugin_manager manager, plugin p, loader_impl return 1; } - init_order = vector_size(impl->handle_impl_init_order); + if (init_order_not_initialized) + { + init_order = vector_size(impl->handle_impl_init_order); - vector_push_back_empty(impl->handle_impl_init_order); + vector_push_back_empty(impl->handle_impl_init_order); + } handle = iface->load_from_package(impl, path); @@ -1091,7 +1454,10 @@ int loader_impl_load_from_package(plugin_manager manager, plugin p, loader_impl { if (loader_impl_handle_register(manager, impl, subpath, handle_impl, handle_ptr) == 0) { - vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + if (init_order_not_initialized) + { + vector_set_var(impl->handle_impl_init_order, init_order, handle_impl); + } return 0; } @@ -1103,7 +1469,10 @@ int loader_impl_load_from_package(plugin_manager manager, plugin p, loader_impl set_remove(impl->handle_impl_path_map, handle_impl->path); } + if (init_order_not_initialized) { + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ size_t iterator; for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) @@ -1123,16 +1492,21 @@ int loader_impl_load_from_package(plugin_manager manager, plugin p, loader_impl } else { - size_t iterator; - - for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + if (init_order_not_initialized) { - loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); + /* Here we delete all the subsequent loaded scripts because this script can load others, + and once it is destroyed it must clear all of them */ + size_t iterator; - loader_impl_destroy_handle(iterator_handle_impl); - } + for (iterator = init_order + 1; iterator < vector_size(impl->handle_impl_init_order); ++iterator) + { + loader_handle_impl iterator_handle_impl = vector_at_type(impl->handle_impl_init_order, iterator, loader_handle_impl); + + loader_impl_destroy_handle(iterator_handle_impl); + } - vector_pop_back(impl->handle_impl_init_order); + vector_pop_back(impl->handle_impl_init_order); + } } } } @@ -1150,7 +1524,7 @@ void *loader_impl_get_handle(loader_impl impl, const char *name) return NULL; } -void loader_impl_set_options(loader_impl impl, void *options) +void loader_impl_set_options(loader_impl impl, value options) { if (impl != NULL && options != NULL) { @@ -1158,7 +1532,7 @@ void loader_impl_set_options(loader_impl impl, void *options) } } -void *loader_impl_get_options(loader_impl impl) +value loader_impl_get_options(loader_impl impl) { if (impl != NULL) { @@ -1168,6 +1542,41 @@ void *loader_impl_get_options(loader_impl impl) return NULL; } +value loader_impl_get_option(loader_impl impl, const char *field) +{ + value *options_map = value_to_map(impl->options); + size_t i, size = value_type_count(impl->options); + + for (i = 0; i < size; ++i) + { + value *options_tuple = value_to_array(options_map[i]); + + if (value_type_id(options_tuple[0]) == TYPE_STRING) + { + const char *str = value_to_string(options_tuple[0]); + + if (strncmp(str, field, value_type_size(options_tuple[0])) == 0) + { + return options_tuple[1]; + } + } + } + + return NULL; +} + +int loader_impl_get_option_host(loader_impl impl) +{ + value host = loader_impl_get_option(impl, "host"); + + if (host != NULL && value_type_id(host) == TYPE_BOOL) + { + return value_to_bool(host); + } + + return 0; +} + int loader_impl_handle_initialize(plugin_manager manager, plugin p, loader_impl impl, const loader_path name, void **handle_ptr) { if (impl != NULL) @@ -1381,38 +1790,30 @@ value loader_impl_metadata_handle(loader_handle_impl handle_impl) return v; } -int loader_impl_metadata_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - loader_impl_metadata_cb_iterator metadata_iterator = (loader_impl_metadata_cb_iterator)args; - - (void)s; - (void)key; - - metadata_iterator->values[metadata_iterator->iterator] = loader_impl_metadata_handle((loader_handle_impl)val); - - if (metadata_iterator->values[metadata_iterator->iterator] != NULL) - { - ++metadata_iterator->iterator; - } - - return 0; -} - value loader_impl_metadata(loader_impl impl) { - struct loader_impl_metadata_cb_iterator_type metadata_iterator; - - value v = value_create_array(NULL, set_size(impl->handle_impl_path_map)); + value *values, v = value_create_array(NULL, set_size(impl->handle_impl_path_map)); + struct set_iterator_type it; + size_t values_it; if (v == NULL) { return NULL; } - metadata_iterator.iterator = 0; - metadata_iterator.values = value_to_array(v); + values = value_to_map(v); - set_iterate(impl->handle_impl_path_map, &loader_impl_metadata_cb_iterate, (set_cb_iterate_args)&metadata_iterator); + for (set_iterator_begin(&it, impl->handle_impl_path_map), values_it = 0; set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + loader_handle_impl handle_impl = set_iterator_value(&it); + + values[values_it] = loader_impl_metadata_handle(handle_impl); + + if (values[values_it] != NULL) + { + ++values_it; + } + } return v; } @@ -1453,40 +1854,6 @@ int loader_impl_clear(void *handle) return 1; } -int loader_impl_destroy_type_map_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - (void)args; - - if (val != NULL) - { - type t = val; - - type_destroy(t); - - return 0; - } - - return 1; -} - -int loader_impl_destroy_exec_path_map_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - (void)args; - - if (val != NULL) - { - vector paths = val; - - vector_destroy(paths); - } - - return 0; -} - void loader_impl_destroy_objects(loader_impl impl) { /* This iterates through all functions, classes objects and types, @@ -1525,7 +1892,16 @@ void loader_impl_destroy_objects(loader_impl impl) set_destroy(impl->handle_impl_map); /* Destroy all the types */ - set_iterate(impl->type_info_map, &loader_impl_destroy_type_map_cb_iterate, NULL); + { + struct set_iterator_type it; + + for (set_iterator_begin(&it, impl->type_info_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + type t = set_iterator_value(&it); + + type_destroy(t); + } + } set_destroy(impl->type_info_map); } @@ -1533,12 +1909,55 @@ void loader_impl_destroy_objects(loader_impl impl) void loader_impl_destroy_deallocate(loader_impl impl) { - set_iterate(impl->exec_path_map, &loader_impl_destroy_exec_path_map_cb_iterate, NULL); + struct set_iterator_type it; + + /* Destroy execution path map */ + for (set_iterator_begin(&it, impl->exec_path_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + vector paths = set_iterator_value(&it); + + vector_destroy(paths); + } set_destroy(impl->exec_path_map); + /* Destroy context */ context_destroy(impl->ctx); + /* Destroy options */ + if (impl->options != NULL) + { + value_type_destroy(impl->options); + } + + /* Destroy detour map */ + for (set_iterator_begin(&it, impl->detour_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + detour_handle handle = set_iterator_value(&it); + + detour_unload(impl->d, handle); + } + + set_destroy(impl->detour_map); + + /* Unload all the dependencies. + This must be done when the plugin dynlink handle (aka the loader) gets unloaded, + at this point it is not unloaded yet, because the plugin destructor is called before doing: + dynlink_unload(p->descriptor->handle); + As the destroy mechanism requires the loaders to be unloaded at the end after all the destroy methods of all + loaders have been called, this generates an ourobros that cannot be solved easily. In any case, + this method still should work because normally those handles are reference counted and we increment + the reference counter at the beginning, so they will be properly unloaded when the dynlink handle gets unloaded. + */ + for (set_iterator_begin(&it, impl->library_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + dynlink dependency = set_iterator_value(&it); + + dynlink_unload(dependency); + } + + set_destroy(impl->library_map); + free(impl); } @@ -1567,6 +1986,11 @@ void loader_impl_destroy(plugin p, loader_impl impl) impl->init = 1; } + + /* Remove the loader library from the library list */ + plugin_descriptor desc = plugin_desc(p); + + set_remove(impl->library_map, (set_key)desc->library_name); } else { diff --git a/source/loader/source/loader_manager_impl.c b/source/loader/source/loader_manager_impl.c index b22fa15273..7e6308d4b6 100644 --- a/source/loader/source/loader_manager_impl.c +++ b/source/loader/source/loader_manager_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,8 +26,8 @@ #include -#include #include +#include #include @@ -52,8 +52,8 @@ static void *loader_manager_impl_is_destroyed_ptr = NULL; vector loader_manager_impl_script_paths_initialize(void) { - portability_executable_path_str exe_path_str = { 0 }; - portability_executable_path_length exe_path_str_length = 0; + portability_working_path_str cwd_path_str = { 0 }; + portability_working_path_length cwd_path_str_length = 0; char *script_path = NULL; size_t script_path_size = 0; vector script_paths = vector_create_type(char *); @@ -63,11 +63,9 @@ vector loader_manager_impl_script_paths_initialize(void) return NULL; } - if (portability_executable_path(exe_path_str, &exe_path_str_length) == 0) + if (portability_working_path(cwd_path_str, &cwd_path_str_length) == 0) { - size_t exe_directory_size = portability_path_get_directory_inplace(exe_path_str, exe_path_str_length + 1); - - script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, exe_path_str, exe_directory_size, &script_path_size); + script_path = environment_variable_path_create(LOADER_SCRIPT_PATH, cwd_path_str, cwd_path_str_length + 1, &script_path_size); } else { diff --git a/source/loaders/CMakeLists.txt b/source/loaders/CMakeLists.txt index 2d992ee6f5..374d6e4a5d 100644 --- a/source/loaders/CMakeLists.txt +++ b/source/loaders/CMakeLists.txt @@ -26,6 +26,158 @@ option(OPTION_BUILD_LOADERS_RPC "Build cURL Remote Procedure Call loader plugin. option(OPTION_BUILD_LOADERS_TS "Build TypeScript 3.9.7 Runtime loader plugin." OFF) option(OPTION_BUILD_LOADERS_WASM "Build WebAssembly Virtual Machine loader plugin." OFF) +# +# Configuration for loaders +# +# The following list of macros is used for generating a configuration file which includes +# dependencies, this is required because now loaders can either load the dependencies or +# use the existing dependencies if MetaCall is being loaded from python.exe, node.exe +# or similar... so we require to delay the loader dependencies until we know if +# their dependencies are already present. +# +# This set of macros provies a flexible way of defining the configuration and dependencies. +# +# 1) The most basic case, let's assume we have the dependencies in the system, like in Python: +# +# loader_configuration_begin(py_loader) +# loader_configuration_deps(python "${Python3_LIBRARY}") +# loader_configuartion_end() +# +# 2) Maybe you want to have multiple paths for a library: +# +# loader_configuration_begin(node_loader) +# loader_configuration_deps(node "/path/to/libnode.so" "/alternative/path/to/libnode.so") +# loader_configuartion_end() +# +# 3) Or the dependencies are compiled by you and you so you have different folders for +# for development (build folder) and for when installing it: +# +# loader_configuration_begin(node_loader) +# loader_configuration_deps(node "/path/to/build/folder/libnode.so") +# loader_configuartion_end_development() +# +# loader_configuration_begin(node_loader) +# loader_configuration_deps(node "/path/to/install/folder/libnode.so") +# loader_configuartion_end_install() +# +# 4) Or you have a custom template because your loader needs a configuration with more fields: +# +# loader_configuration_begin(cs_loader) +# loader_configuration_deps(netcore "/path/to/build/folder/libnetcore.so") +# loader_configuartion_end() +# +# You can do any combination of those for defining the configuration of your loaders. +# + +# Define loader template configuration +set(LOADER_CONFIGURATION_DEFAULT_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/loader.json.in") + +# Define loader configuration for a specific loader +macro(loader_configuration_begin TARGET) + set(LOADER_DEPENDENCIES "") + set(OPTIONAL_TEMPLATE "${ARGV1}") + + # Optional argument for template + if(NOT "${ARGV1}" STREQUAL "") + set(LOADER_CONFIGURATION_TEMPLATE "${ARGV1}") + else() + set(LOADER_CONFIGURATION_TEMPLATE "${LOADER_CONFIGURATION_DEFAULT_TEMPLATE}") + endif() + + set(LOADER_CONFIGURATION_TARGET "${TARGET}") +endmacro() + +# Generate configuration with search paths for a loader +# +# "search_paths": [ "C:/Program Files/ruby/bin/ruby_builtin_dlls" ], +# +macro(loader_configuration_paths LIBRARY_PATHS_LIST) + if(NOT "${LIBRARY_PATHS_LIST}" STREQUAL "") + # Normalize the paths + string(REPLACE "\\" "/" LIBRARY_PATHS "${LIBRARY_PATHS_LIST}") + + # Convert to JSON + string(REPLACE ";" "\", \"" LOADER_SEARCH_PATHS "\"${LIBRARY_PATHS}\"") + else() + set(LOADER_SEARCH_PATHS) + endif() +endmacro() + +# Generate configuration with dependencies for a loader +# +# node_loader: +# "node": [ "/path/to/libnode.so", "/alternative/path/to/libnode.so" ], +# +# c_loader: +# "libffi": [ ... ], +# "libclang": [ ... ], +# "libtcc": [ ... ] +macro(loader_configuration_deps LIBRARY) + # Add new line from previous dependency + if(NOT "${LOADER_DEPENDENCIES}" STREQUAL "") + string(APPEND LOADER_DEPENDENCIES ",\n\t\t") + endif() + + # Define the library + string(APPEND LOADER_DEPENDENCIES "\"${LIBRARY}\": [") + + # Define the paths + set(FIRST_ARGUMENT 0) + foreach(DEPENDENCY IN ITEMS ${ARGN}) + if(${FIRST_ARGUMENT} EQUAL 0) + # Set first path + string(APPEND LOADER_DEPENDENCIES "\"${DEPENDENCY}\"") + set(FIRST_ARGUMENT 1) + else() + # Set the rest of the paths + string(APPEND LOADER_DEPENDENCIES ", \"${DEPENDENCY}\"") + endif() + endforeach() + + # Finalize the list + string(APPEND LOADER_DEPENDENCIES "]") +endmacro() + +# Commit development version +macro(loader_configuartion_end_development) + if(NOT DEFINED LOADER_CONFIGURATION_TEMPLATE OR NOT DEFINED LOADER_CONFIGURATION_TARGET) + return() + endif() + + configure_file(${LOADER_CONFIGURATION_TEMPLATE} ${CONFIGURATION_DIR}/${LOADER_CONFIGURATION_TARGET}.json) + + unset(LOADER_DEPENDENCIES) + unset(LOADER_CONFIGURATION_TEMPLATE) + unset(LOADER_CONFIGURATION_TARGET) +endmacro() + +# Commit install version +macro(loader_configuartion_end_install) + if(NOT DEFINED LOADER_CONFIGURATION_TEMPLATE OR NOT DEFINED LOADER_CONFIGURATION_TARGET) + return() + endif() + + configure_file(${LOADER_CONFIGURATION_TEMPLATE} ${CONFIGURATION_DIR}/install/configurations/${LOADER_CONFIGURATION_TARGET}.json) + + unset(LOADER_DEPENDENCIES) + unset(LOADER_CONFIGURATION_TEMPLATE) + unset(LOADER_CONFIGURATION_TARGET) +endmacro() + +# Commit both versions +macro(loader_configuartion_end) + if(NOT DEFINED LOADER_CONFIGURATION_TEMPLATE OR NOT DEFINED LOADER_CONFIGURATION_TARGET) + return() + endif() + + configure_file(${LOADER_CONFIGURATION_TEMPLATE} ${CONFIGURATION_DIR}/${LOADER_CONFIGURATION_TARGET}.json) + configure_file(${LOADER_CONFIGURATION_TEMPLATE} ${CONFIGURATION_DIR}/install/configurations/${LOADER_CONFIGURATION_TARGET}.json) + + unset(LOADER_DEPENDENCIES) + unset(LOADER_CONFIGURATION_TEMPLATE) + unset(LOADER_CONFIGURATION_TARGET) +endmacro() + # Plugin packages add_subdirectory(c_loader) # Foreign Function Interface library add_subdirectory(cob_loader) # GNU/Cobol 2.2 Runtime @@ -49,34 +201,18 @@ add_subdirectory(rpc_loader) # cURL Remote Procedure Call add_subdirectory(ts_loader) # TypeScript 3.9.7 add_subdirectory(wasm_loader) # WebAssembly Virtual Machine -# Optionally enable loader dependencies utility -macro(add_loader_dependencies target) - set(loaders_map_c_loader OPTION_BUILD_LOADERS_C) - set(loaders_map_cob_loader OPTION_BUILD_LOADERS_COB) - set(loaders_map_cr_loader OPTION_BUILD_LOADERS_CR) - set(loaders_map_cs_loader OPTION_BUILD_LOADERS_DART) - set(loaders_map_dart_loader OPTION_BUILD_LOADERS_CS) - set(loaders_map_ext_loader OPTION_BUILD_LOADERS_EXT) - set(loaders_map_file_loader OPTION_BUILD_LOADERS_FILE) - set(loaders_map_java_loader OPTION_BUILD_LOADERS_JAVA) - set(loaders_map_jl_loader OPTION_BUILD_LOADERS_JL) - set(loaders_map_jsm_loader OPTION_BUILD_LOADERS_JSM) - set(loaders_map_js_loader OPTION_BUILD_LOADERS_JS) - set(loaders_map_llvm_loader OPTION_BUILD_LOADERS_LLVM) - set(loaders_map_lua_loader OPTION_BUILD_LOADERS_LUA) - set(loaders_map_mock_loader OPTION_BUILD_LOADERS_MOCK) - set(loaders_map_node_loader OPTION_BUILD_LOADERS_NODE) - set(loaders_map_py_loader OPTION_BUILD_LOADERS_PY) - set(loaders_map_rb_loader OPTION_BUILD_LOADERS_RB) - set(loaders_map_rs_loader OPTION_BUILD_LOADERS_RS) - set(loaders_map_rpc_loader OPTION_BUILD_LOADERS_RPC) - set(loaders_map_ts_loader OPTION_BUILD_LOADERS_TS) - set(loaders_map_wasm_loader OPTION_BUILD_LOADERS_WASM) - +# Optionally enable loader dependencies utility (for tests) +macro(add_loader_dependencies TARGET) set(LOADERS_LIST) - foreach(loader ${ARGN}) - if(${loaders_map_${loader}}) + foreach(LOADER ${ARGN}) + # Loaders come in the form of: py_loader, node_loader, ... + # Convert them into OPTION_BUILD_LOADERS_PY, OPTION_BUILD_LOADERS_NODE, ... + string(REPLACE "_loader" "" LOADER_TAG "${LOADER}") + string(TOUPPER "${LOADER_TAG}" LOADER_TAG) + + # Check if the loader is enabled + if(${OPTION_BUILD_LOADERS_${LOADER_TAG}}) set(LOADERS_LIST ${LOADERS_LIST} ${loader} @@ -85,6 +221,6 @@ macro(add_loader_dependencies target) endforeach() if(LOADERS_LIST) - add_dependencies(${target} ${LOADERS_LIST}) + add_dependencies(${TARGET} ${LOADERS_LIST}) endif() endmacro() diff --git a/source/loaders/c_loader/CMakeLists.txt b/source/loaders/c_loader/CMakeLists.txt index cc2c092102..e418078d95 100644 --- a/source/loaders/c_loader/CMakeLists.txt +++ b/source/loaders/c_loader/CMakeLists.txt @@ -203,7 +203,7 @@ target_compile_features(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/c_loader/include/c_loader/c_loader.h b/source/loaders/c_loader/include/c_loader/c_loader.h index 0e083cb018..9d92fd0f7a 100644 --- a/source/loaders/c_loader/include/c_loader/c_loader.h +++ b/source/loaders/c_loader/include/c_loader/c_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading c code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif C_LOADER_API loader_impl_interface c_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(c_loader_impl_interface_singleton); - C_LOADER_API const char *c_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(c_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/c_loader/include/c_loader/c_loader_impl.h b/source/loaders/c_loader/include/c_loader/c_loader_impl.h index fa9b9fafa4..46de1b4ac9 100644 --- a/source/loaders/c_loader/include/c_loader/c_loader_impl.h +++ b/source/loaders/c_loader/include/c_loader/c_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading c code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/c_loader/source/c_loader.c b/source/loaders/c_loader/source/c_loader.c index 42ace7dc06..328db89cc5 100644 --- a/source/loaders/c_loader/source/c_loader.c +++ b/source/loaders/c_loader/source/c_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading c code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *c_loader_print_info(void) { static const char c_loader_info[] = "C Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef C_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/c_loader/source/c_loader_impl.cpp b/source/loaders/c_loader/source/c_loader_impl.cpp index 52ead7b7cd..70470488c5 100644 --- a/source/loaders/c_loader/source/c_loader_impl.cpp +++ b/source/loaders/c_loader/source/c_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading c code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,9 +52,11 @@ namespace fs = std::experimental::filesystem; #endif #include +#include #include #include +#include #include /* LibFFI */ @@ -74,17 +76,81 @@ 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 &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 files; - virtual ~loader_impl_c_handle_base_type() {} + virtual ~loader_impl_c_handle_file_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 &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) @@ -114,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 &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 +struct loader_impl_c_handle_tcc_type : T { public: TCCState *state; @@ -136,6 +255,11 @@ typedef struct loader_impl_c_handle_tcc_type : loader_impl_c_handle_base_type } } + bool recursive_includes() + { + return false; + } + bool initialize(loader_impl_c c_impl) { this->state = tcc_new(); @@ -198,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(this), &c_loader_impl_discover_symbols); + tcc_list_symbols(this->state, static_cast(&symbols), &c_loader_impl_discover_symbols); /* Parse the AST and register functions */ return c_loader_impl_discover_ast(impl, this, ctx); @@ -213,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_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_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; @@ -232,6 +361,11 @@ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_typ } } + bool recursive_includes() + { + return true; + } + bool initialize(loader_impl_c c_impl, const loader_path path) { std::string lib_path_str(path); @@ -303,7 +437,7 @@ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_typ { /* This function will try to check if the library exists before loading it, so we avoid error messages from dynlink when guessing the file path for relative load from file */ - dynlink_name_impl platform_name; + dynlink_path platform_name; dynlink_platform_name(library_name, platform_name); @@ -371,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); @@ -504,6 +629,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 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)) + { + *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(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); @@ -578,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(ctx); + std::map *symbols = static_cast *>(ctx); - c_handle->symbols.insert(std::pair(name, addr)); + symbols->insert(std::pair(name, addr)); } static bool c_loader_impl_file_exists(const loader_path path) @@ -621,10 +835,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; @@ -636,8 +858,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(impl); @@ -649,9 +870,10 @@ 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)) { - 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.", @@ -660,10 +882,9 @@ 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) + if (value_id == TYPE_FUNCTION) { c_loader_closure_value *closure = new c_loader_closure_value(static_cast(type_derived(t))); @@ -671,19 +892,52 @@ function_return function_c_interface_invoke(function func, function_impl impl, f closures.push_back(closure); } - else + else if (value_id == TYPE_STRING || value_id == TYPE_BUFFER) + { + /* 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 (value_id == TYPE_PTR) + { + c_function->values[args_count] = args[args_count]; + } + else if (value_id == TYPE_ARRAY) + { + c_loader_array_type *array = static_cast(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(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]); } + 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; @@ -693,9 +947,60 @@ 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), result_ptr, c_function->values); - ffi_call(&c_function->cif, FFI_FN(c_function->address), value_data(ret), 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); + } + } + + for (size_t args_count = 0; args_count < args_size; ++args_count) + { + type_id value_id = value_type_id((value)args[args_count]); + + if (value_id == TYPE_ARRAY) + { + c_loader_array_type::free_c_array(static_cast(c_function->values[args_count])); + } } /* Clear allocated closures if any */ @@ -788,6 +1093,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" }, @@ -796,6 +1102,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" }, @@ -804,6 +1111,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" }, @@ -812,7 +1120,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" }, @@ -826,6 +1136,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 */ @@ -894,7 +1209,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) { @@ -920,6 +1235,20 @@ static type_id c_loader_impl_clang_type(loader_impl impl, CXCursor cursor, CXTyp return TYPE_PTR; } + case CXType_ConstantArray: + 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(array_type); + + return TYPE_ARRAY; + } + + return TYPE_INVALID; + } + case CXType_FunctionProto: case CXType_FunctionNoProto: { c_loader_closure_type *closure_type = new c_loader_closure_type(impl); @@ -952,7 +1281,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: @@ -1022,12 +1356,18 @@ static int c_loader_impl_discover_signature(loader_impl impl, loader_impl_c_hand symbol_name.insert(0, 1, '_'); #endif + if (scope_get(sp, symbol_name.c_str()) != NULL) + { + log_write("metacall", LOG_LEVEL_WARNING, "Symbol '%s' redefined, skipping the function", func_name.c_str()); + return 0; + } + const void *address = c_handle->symbol(symbol_name); if (address == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Symbol '%s' not found, skipping the function", func_name.c_str()); - return 1; + log_write("metacall", LOG_LEVEL_WARNING, "Symbol '%s' not found, skipping the function", func_name.c_str()); + return 0; } loader_impl_c_function c_function = new loader_impl_c_function_type(address); @@ -1076,13 +1416,17 @@ 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(data); - if (clang_Location_isFromMainFile(clang_getCursorLocation(cursor)) == 0) + /* Include recursively when disabled, include only the header inlcuded is populated when enabled */ + if (visitor_data->c_handle->recursive_includes() == false) { - return CXChildVisit_Continue; + if (clang_Location_isFromMainFile(clang_getCursorLocation(cursor)) == 0) + { + return CXChildVisit_Continue; + } } CXCursorKind kind = clang_getCursorKind(cursor); @@ -1102,6 +1446,7 @@ static CXChildVisitResult c_loader_impl_discover_visitor(CXCursor cursor, CXCurs static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_base c_handle, context ctx) { + loader_impl_c c_impl = static_cast(loader_impl_get(impl)); c_loader_impl_discover_visitor_data_type data = { impl, c_handle, @@ -1109,36 +1454,37 @@ static int c_loader_impl_discover_ast(loader_impl impl, loader_impl_c_handle_bas 0 }; - for (std::string file : c_handle->files) - { - CXIndex index = clang_createIndex(0, 0); - CXTranslationUnit unit = clang_parseTranslationUnit( - index, - file.c_str(), nullptr, 0, - nullptr, 0, - CXTranslationUnit_None); + std::vector includes; + std::vector command_line_args; - 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(&data)); + /* Otherwise, check the execution paths */ + for (auto exec_path : c_impl->execution_paths) + { + includes.push_back("-I" + exec_path); + command_line_args.push_back(includes.back().c_str()); + } - clang_disposeTranslationUnit(unit); - clang_disposeIndex(index); + if (c_handle->discover_visitor(command_line_args, static_cast(&data)) != 0) + { + return 1; } 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_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) { @@ -1189,7 +1535,7 @@ loader_handle c_loader_impl_load_from_file(loader_impl impl, const loader_path p } } - if (tcc_relocate(c_handle->state, TCC_RELOCATE_AUTO) == -1) + if (c_loader_impl_tcc_relocate(c_handle->state) == -1) { log_write("metacall", LOG_LEVEL_ERROR, "TCC failed to relocate"); goto error; @@ -1205,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_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; @@ -1221,13 +1567,15 @@ loader_handle c_loader_impl_load_from_memory(loader_impl impl, const loader_name goto error; } - if (tcc_relocate(c_handle->state, TCC_RELOCATE_AUTO) == -1) + if (c_loader_impl_tcc_relocate(c_handle->state) == -1) { log_write("metacall", LOG_LEVEL_ERROR, "TCC failed to relocate"); 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/loaders/cob_loader/CMakeLists.txt b/source/loaders/cob_loader/CMakeLists.txt index cd0327d7ce..a22cbf01e1 100644 --- a/source/loaders/cob_loader/CMakeLists.txt +++ b/source/loaders/cob_loader/CMakeLists.txt @@ -162,7 +162,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/cob_loader/include/cob_loader/cob_loader.h b/source/loaders/cob_loader/include/cob_loader/cob_loader.h index 92c6412aa3..f7a3b7d667 100644 --- a/source/loaders/cob_loader/include/cob_loader/cob_loader.h +++ b/source/loaders/cob_loader/include/cob_loader/cob_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading cobol code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif COB_LOADER_API loader_impl_interface cob_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cob_loader_impl_interface_singleton); - COB_LOADER_API const char *cob_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cob_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cob_loader/include/cob_loader/cob_loader_impl.h b/source/loaders/cob_loader/include/cob_loader/cob_loader_impl.h index 71a50c9493..5822c4008d 100644 --- a/source/loaders/cob_loader/include/cob_loader/cob_loader_impl.h +++ b/source/loaders/cob_loader/include/cob_loader/cob_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading cobol code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cob_loader/source/cob_loader.c b/source/loaders/cob_loader/source/cob_loader.c index 450fc82a01..ddeb4851ef 100644 --- a/source/loaders/cob_loader/source/cob_loader.c +++ b/source/loaders/cob_loader/source/cob_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading cobol code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *cob_loader_print_info(void) { static const char cob_loader_info[] = "Cobol Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef COB_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/cob_loader/source/cob_loader_impl.cpp b/source/loaders/cob_loader/source/cob_loader_impl.cpp index 6fff1d4712..b74589782f 100644 --- a/source/loaders/cob_loader/source/cob_loader_impl.cpp +++ b/source/loaders/cob_loader/source/cob_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading cobol code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/CMakeLists.txt b/source/loaders/cr_loader/CMakeLists.txt index 9a40a3bef2..305875d48b 100644 --- a/source/loaders/cr_loader/CMakeLists.txt +++ b/source/loaders/cr_loader/CMakeLists.txt @@ -154,7 +154,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/cr_loader/crystal/cr_loader_impl.cr b/source/loaders/cr_loader/crystal/cr_loader_impl.cr index 8f1274f98c..34c33a319e 100644 --- a/source/loaders/cr_loader/crystal/cr_loader_impl.cr +++ b/source/loaders/cr_loader/crystal/cr_loader_impl.cr @@ -2,7 +2,7 @@ # Loader Library by Parra Studios # A plugin for loading crystal code at run-time into a process. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/crystal/main.cr b/source/loaders/cr_loader/crystal/main.cr index 3068b919b5..4060807e12 100644 --- a/source/loaders/cr_loader/crystal/main.cr +++ b/source/loaders/cr_loader/crystal/main.cr @@ -2,7 +2,7 @@ # Loader Library by Parra Studios # A plugin for loading crystal code at run-time into a process. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/crystal/metacall.cr b/source/loaders/cr_loader/crystal/metacall.cr index a6b306d71c..d266a534a0 100644 --- a/source/loaders/cr_loader/crystal/metacall.cr +++ b/source/loaders/cr_loader/crystal/metacall.cr @@ -2,7 +2,7 @@ # Loader Library by Parra Studios # A plugin for loading crystal code at run-time into a process. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/include/cr_loader/cr_loader.h b/source/loaders/cr_loader/include/cr_loader/cr_loader.h index 628f387e66..936dade8a0 100644 --- a/source/loaders/cr_loader/include/cr_loader/cr_loader.h +++ b/source/loaders/cr_loader/include/cr_loader/cr_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading crystal code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CR_LOADER_API loader_impl_interface cr_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cr_loader_impl_interface_singleton); - CR_LOADER_API const char *cr_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cr_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cr_loader/include/cr_loader/cr_loader_impl.h b/source/loaders/cr_loader/include/cr_loader/cr_loader_impl.h index 7abbf29aba..daa8e1edb6 100644 --- a/source/loaders/cr_loader/include/cr_loader/cr_loader_impl.h +++ b/source/loaders/cr_loader/include/cr_loader/cr_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading crystal code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/include/cr_loader/cr_loader_impl_main.h b/source/loaders/cr_loader/include/cr_loader/cr_loader_impl_main.h index c4142210e0..9c30090887 100644 --- a/source/loaders/cr_loader/include/cr_loader/cr_loader_impl_main.h +++ b/source/loaders/cr_loader/include/cr_loader/cr_loader_impl_main.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading crystal code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cr_loader/source/cr_loader.c b/source/loaders/cr_loader/source/cr_loader.c index 8788d6a7a9..f96bbe3b5d 100644 --- a/source/loaders/cr_loader/source/cr_loader.c +++ b/source/loaders/cr_loader/source/cr_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading crystal code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *cr_loader_print_info(void) { static const char cr_loader_info[] = "Crystal Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef CR_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/cs_loader/CMakeLists.txt b/source/loaders/cs_loader/CMakeLists.txt index 3eedab81b3..37b4a7ac22 100644 --- a/source/loaders/cs_loader/CMakeLists.txt +++ b/source/loaders/cs_loader/CMakeLists.txt @@ -222,7 +222,7 @@ target_compile_features(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC @@ -235,13 +235,18 @@ target_link_libraries(${target} # Configuration # +set(CS_LOADER_CONFIG_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/data/cs_loader.json.in") string(REPLACE "\\" "/" DOTNET_CORE_PATH "${DOTNET_CORE_PATH}") -set(DOTNET_CORE_LOADER_ASSEMBLY_PATH ${PROJECT_OUTPUT_DIR}/CSLoader.dll) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/cs_loader.json.in ${CONFIGURATION_DIR}/cs_loader.json) +# Development +loader_configuration_begin(cs_loader "${CS_LOADER_CONFIG_TEMPLATE}") +set(DOTNET_CORE_LOADER_ASSEMBLY_PATH ${PROJECT_OUTPUT_DIR}/CSLoader.dll) +loader_configuartion_end_development() -set(DOTNET_CORE_LOADER_ASSEMBLY_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/CSLoader.dll) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/cs_loader.json.in ${CONFIGURATION_DIR}/install/configurations/cs_loader.json) +# Install +loader_configuration_begin(cs_loader "${CS_LOADER_CONFIG_TEMPLATE}") +set(DOTNET_CORE_LOADER_ASSEMBLY_PATH ${PROJECT_OUTPUT_DIR}/CSLoader.dll) +loader_configuartion_end_install() # # Deployment diff --git a/source/loaders/cs_loader/data/cs_loader.json.in b/source/loaders/cs_loader/data/cs_loader.json.in index b701dec8b8..a570e08689 100644 --- a/source/loaders/cs_loader/data/cs_loader.json.in +++ b/source/loaders/cs_loader/data/cs_loader.json.in @@ -1,4 +1,4 @@ { - "dotnet_root":"@DOTNET_CORE_PATH@", - "dotnet_loader_assembly_path":"@DOTNET_CORE_LOADER_ASSEMBLY_PATH@" + "dotnet_root": "@DOTNET_CORE_PATH@", + "dotnet_loader_assembly_path": "@DOTNET_CORE_LOADER_ASSEMBLY_PATH@" } diff --git a/source/loaders/cs_loader/include/cs_loader/cs_loader.h b/source/loaders/cs_loader/include/cs_loader/cs_loader.h index 546a515caf..37aa49c71a 100644 --- a/source/loaders/cs_loader/include/cs_loader/cs_loader.h +++ b/source/loaders/cs_loader/include/cs_loader/cs_loader.h @@ -13,20 +13,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif CS_LOADER_API loader_impl_interface cs_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(cs_loader_impl_interface_singleton); - CS_LOADER_API const char *cs_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(cs_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/cs_loader/include/cs_loader/defs.h b/source/loaders/cs_loader/include/cs_loader/defs.h index ba55028007..9498288aa5 100644 --- a/source/loaders/cs_loader/include/cs_loader/defs.h +++ b/source/loaders/cs_loader/include/cs_loader/defs.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/host_environment.h b/source/loaders/cs_loader/include/cs_loader/host_environment.h index 27f57baa3a..81388cab50 100644 --- a/source/loaders/cs_loader/include/cs_loader/host_environment.h +++ b/source/loaders/cs_loader/include/cs_loader/host_environment.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/netcore.h b/source/loaders/cs_loader/include/cs_loader/netcore.h index a61d3a2e07..3d5cf0b5f0 100644 --- a/source/loaders/cs_loader/include/cs_loader/netcore.h +++ b/source/loaders/cs_loader/include/cs_loader/netcore.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/netcore_linux.h b/source/loaders/cs_loader/include/cs_loader/netcore_linux.h index 803d656d82..09369c3890 100644 --- a/source/loaders/cs_loader/include/cs_loader/netcore_linux.h +++ b/source/loaders/cs_loader/include/cs_loader/netcore_linux.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/netcore_win.h b/source/loaders/cs_loader/include/cs_loader/netcore_win.h index ae9ee3f4cb..8de3705bc0 100644 --- a/source/loaders/cs_loader/include/cs_loader/netcore_win.h +++ b/source/loaders/cs_loader/include/cs_loader/netcore_win.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/simple_netcore.h b/source/loaders/cs_loader/include/cs_loader/simple_netcore.h index 557d83df2d..01582ec94f 100644 --- a/source/loaders/cs_loader/include/cs_loader/simple_netcore.h +++ b/source/loaders/cs_loader/include/cs_loader/simple_netcore.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/string_buffer.h b/source/loaders/cs_loader/include/cs_loader/string_buffer.h index 8b0b387e86..a89ecf6dc1 100644 --- a/source/loaders/cs_loader/include/cs_loader/string_buffer.h +++ b/source/loaders/cs_loader/include/cs_loader/string_buffer.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/include/cs_loader/utils.hpp b/source/loaders/cs_loader/include/cs_loader/utils.hpp index 60311047e7..1a36b45e96 100644 --- a/source/loaders/cs_loader/include/cs_loader/utils.hpp +++ b/source/loaders/cs_loader/include/cs_loader/utils.hpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/cs_loader.c b/source/loaders/cs_loader/source/cs_loader.c index f13e90e8d6..4b19bd5053 100644 --- a/source/loaders/cs_loader/source/cs_loader.c +++ b/source/loaders/cs_loader/source/cs_loader.c @@ -34,7 +34,7 @@ const char *cs_loader_print_info(void) { static const char cs_loader_info[] = "Net Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef CS_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/cs_loader/source/cs_loader_impl.c b/source/loaders/cs_loader/source/cs_loader_impl.c index e33bb466bb..96508759c5 100644 --- a/source/loaders/cs_loader/source/cs_loader_impl.c +++ b/source/loaders/cs_loader/source/cs_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/host_environment.cpp b/source/loaders/cs_loader/source/host_environment.cpp index ba6e51d0e8..9254891e2f 100644 --- a/source/loaders/cs_loader/source/host_environment.cpp +++ b/source/loaders/cs_loader/source/host_environment.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/netcore.cpp b/source/loaders/cs_loader/source/netcore.cpp index 831853825b..b3eb9561dc 100644 --- a/source/loaders/cs_loader/source/netcore.cpp +++ b/source/loaders/cs_loader/source/netcore.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/netcore_linux.cpp b/source/loaders/cs_loader/source/netcore_linux.cpp index 68e6f0fdc2..8f8c38bcdc 100644 --- a/source/loaders/cs_loader/source/netcore_linux.cpp +++ b/source/loaders/cs_loader/source/netcore_linux.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/simple_netcore.cpp b/source/loaders/cs_loader/source/simple_netcore.cpp index 852b0d8040..93e82b2ade 100644 --- a/source/loaders/cs_loader/source/simple_netcore.cpp +++ b/source/loaders/cs_loader/source/simple_netcore.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/cs_loader/source/string_buffer.cpp b/source/loaders/cs_loader/source/string_buffer.cpp index e482f8b4d9..b5a2ab9197 100644 --- a/source/loaders/cs_loader/source/string_buffer.cpp +++ b/source/loaders/cs_loader/source/string_buffer.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading net code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/dart_loader/CMakeLists.txt b/source/loaders/dart_loader/CMakeLists.txt index 7cff11bd5b..b6b48df1fa 100644 --- a/source/loaders/dart_loader/CMakeLists.txt +++ b/source/loaders/dart_loader/CMakeLists.txt @@ -165,7 +165,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/dart_loader/include/dart_loader/dart_loader.h b/source/loaders/dart_loader/include/dart_loader/dart_loader.h index 8b6530480d..1f88094559 100644 --- a/source/loaders/dart_loader/include/dart_loader/dart_loader.h +++ b/source/loaders/dart_loader/include/dart_loader/dart_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading dart code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif DART_LOADER_API loader_impl_interface dart_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(dart_loader_impl_interface_singleton); - DART_LOADER_API const char *dart_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(dart_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/dart_loader/include/dart_loader/dart_loader_impl.h b/source/loaders/dart_loader/include/dart_loader/dart_loader_impl.h index 7e19d115b7..f89691f7f9 100644 --- a/source/loaders/dart_loader/include/dart_loader/dart_loader_impl.h +++ b/source/loaders/dart_loader/include/dart_loader/dart_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading dart code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/dart_loader/source/dart_loader.c b/source/loaders/dart_loader/source/dart_loader.c index df693fc416..c1486b9a8d 100644 --- a/source/loaders/dart_loader/source/dart_loader.c +++ b/source/loaders/dart_loader/source/dart_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading dart code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *dart_loader_print_info(void) { static const char dart_loader_info[] = "Dart Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef DART_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/dart_loader/source/dart_loader_impl.cc b/source/loaders/dart_loader/source/dart_loader_impl.cc index 92dac094b1..750d52cc7f 100644 --- a/source/loaders/dart_loader/source/dart_loader_impl.cc +++ b/source/loaders/dart_loader/source/dart_loader_impl.cc @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading dart code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/ext_loader/CMakeLists.txt b/source/loaders/ext_loader/CMakeLists.txt index bb850b7ab0..3efbb1d668 100644 --- a/source/loaders/ext_loader/CMakeLists.txt +++ b/source/loaders/ext_loader/CMakeLists.txt @@ -163,7 +163,7 @@ target_compile_features(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/ext_loader/include/ext_loader/ext_loader.h b/source/loaders/ext_loader/include/ext_loader/ext_loader.h index 580ab2ff7d..0ca69aafb8 100644 --- a/source/loaders/ext_loader/include/ext_loader/ext_loader.h +++ b/source/loaders/ext_loader/include/ext_loader/ext_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading extension code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif EXT_LOADER_API loader_impl_interface ext_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(ext_loader_impl_interface_singleton); - EXT_LOADER_API const char *ext_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(ext_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/ext_loader/include/ext_loader/ext_loader_impl.h b/source/loaders/ext_loader/include/ext_loader/ext_loader_impl.h index 7ba7345670..08ef3c1183 100644 --- a/source/loaders/ext_loader/include/ext_loader/ext_loader_impl.h +++ b/source/loaders/ext_loader/include/ext_loader/ext_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading extension code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/ext_loader/source/ext_loader.c b/source/loaders/ext_loader/source/ext_loader.c index 0f2fa35fa1..54dd4aa0d6 100644 --- a/source/loaders/ext_loader/source/ext_loader.c +++ b/source/loaders/ext_loader/source/ext_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading extension code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *ext_loader_print_info(void) { static const char ext_loader_info[] = "Extension Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef FILE_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/ext_loader/source/ext_loader_impl.cpp b/source/loaders/ext_loader/source/ext_loader_impl.cpp index 25b8385a53..ab4f182bd6 100644 --- a/source/loaders/ext_loader/source/ext_loader_impl.cpp +++ b/source/loaders/ext_loader/source/ext_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading extension code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,7 +76,7 @@ typedef struct loader_impl_ext_handle_type union loader_impl_function_cast { - void *ptr; + dynlink_symbol_addr ptr; int (*fn)(void *, void *); }; @@ -142,7 +142,7 @@ dynlink ext_loader_impl_load_from_file_dynlink(const char *path, const char *lib { /* This function will try to check if the library exists before loading it, so we avoid error messages from dynlink when guessing the file path for relative load from file */ - dynlink_name_impl platform_name; + dynlink_path platform_name; dynlink_platform_name(library_name, platform_name); @@ -352,7 +352,7 @@ int ext_loader_impl_discover(loader_impl impl, loader_handle handle, context ctx { loader_impl_function_cast function_cast; - function_cast.ptr = static_cast(ext.addr); + function_cast.ptr = ext.addr; if (function_cast.fn(impl, loader_impl_handle_container_of(impl, handle)) != 0) { diff --git a/source/loaders/file_loader/CMakeLists.txt b/source/loaders/file_loader/CMakeLists.txt index eac4491f72..0a3ec02b35 100644 --- a/source/loaders/file_loader/CMakeLists.txt +++ b/source/loaders/file_loader/CMakeLists.txt @@ -154,7 +154,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/file_loader/include/file_loader/file_loader.h b/source/loaders/file_loader/include/file_loader/file_loader.h index b596e15378..a2fc929b47 100644 --- a/source/loaders/file_loader/include/file_loader/file_loader.h +++ b/source/loaders/file_loader/include/file_loader/file_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading file code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif FILE_LOADER_API loader_impl_interface file_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(file_loader_impl_interface_singleton); - FILE_LOADER_API const char *file_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(file_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/file_loader/include/file_loader/file_loader_impl.h b/source/loaders/file_loader/include/file_loader/file_loader_impl.h index f54d81b457..fd37c415c3 100644 --- a/source/loaders/file_loader/include/file_loader/file_loader_impl.h +++ b/source/loaders/file_loader/include/file_loader/file_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading file code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/file_loader/source/file_loader.c b/source/loaders/file_loader/source/file_loader.c index ec13b8d4c9..1646c1abfa 100644 --- a/source/loaders/file_loader/source/file_loader.c +++ b/source/loaders/file_loader/source/file_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading file code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *file_loader_print_info(void) { static const char file_loader_info[] = "File Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef FILE_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/file_loader/source/file_loader_impl.c b/source/loaders/file_loader/source/file_loader_impl.c index c6596d2ff3..74bad13282 100644 --- a/source/loaders/file_loader/source/file_loader_impl.c +++ b/source/loaders/file_loader/source/file_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading file code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/java_loader/CMakeLists.txt b/source/loaders/java_loader/CMakeLists.txt index 7c26d18712..c59eaa59ad 100644 --- a/source/loaders/java_loader/CMakeLists.txt +++ b/source/loaders/java_loader/CMakeLists.txt @@ -175,7 +175,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/java_loader/include/java_loader/java_loader.h b/source/loaders/java_loader/include/java_loader/java_loader.h index 4db5d86c2e..d241030cd8 100644 --- a/source/loaders/java_loader/include/java_loader/java_loader.h +++ b/source/loaders/java_loader/include/java_loader/java_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading java code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JAVA_LOADER_API loader_impl_interface java_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(java_loader_impl_interface_singleton); - JAVA_LOADER_API const char *java_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(java_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/java_loader/include/java_loader/java_loader_impl.h b/source/loaders/java_loader/include/java_loader/java_loader_impl.h index 2232b5641d..36d42df355 100644 --- a/source/loaders/java_loader/include/java_loader/java_loader_impl.h +++ b/source/loaders/java_loader/include/java_loader/java_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading java code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/java_loader/source/java_loader.c b/source/loaders/java_loader/source/java_loader.c index 9f802a875e..36126eb2e4 100644 --- a/source/loaders/java_loader/source/java_loader.c +++ b/source/loaders/java_loader/source/java_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading java code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *java_loader_print_info(void) { static const char java_loader_info[] = "C Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef JAVA_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/java_loader/source/java_loader_impl.cpp b/source/loaders/java_loader/source/java_loader_impl.cpp index 0baa237f9e..1714679c77 100644 --- a/source/loaders/java_loader/source/java_loader_impl.cpp +++ b/source/loaders/java_loader/source/java_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading java code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/jl_loader/CMakeLists.txt b/source/loaders/jl_loader/CMakeLists.txt index e7a4a3f81c..d628b69cdf 100644 --- a/source/loaders/jl_loader/CMakeLists.txt +++ b/source/loaders/jl_loader/CMakeLists.txt @@ -180,7 +180,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/jl_loader/bootstrap/lib/bootstrap.jl b/source/loaders/jl_loader/bootstrap/lib/bootstrap.jl index dfefa917dd..0b838303b3 100644 --- a/source/loaders/jl_loader/bootstrap/lib/bootstrap.jl +++ b/source/loaders/jl_loader/bootstrap/lib/bootstrap.jl @@ -2,7 +2,7 @@ # Loader Library by Parra Studios # A plugin for loading Julia code at run-time into a process. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/loaders/jl_loader/include/jl_loader/jl_loader.h b/source/loaders/jl_loader/include/jl_loader/jl_loader.h index 574e095044..b77da20f2a 100644 --- a/source/loaders/jl_loader/include/jl_loader/jl_loader.h +++ b/source/loaders/jl_loader/include/jl_loader/jl_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading Julia code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JL_LOADER_API loader_impl_interface jl_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(jl_loader_impl_interface_singleton); - JL_LOADER_API const char *jl_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(jl_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/jl_loader/include/jl_loader/jl_loader_impl.h b/source/loaders/jl_loader/include/jl_loader/jl_loader_impl.h index 6abcd5ab01..e40530c9be 100644 --- a/source/loaders/jl_loader/include/jl_loader/jl_loader_impl.h +++ b/source/loaders/jl_loader/include/jl_loader/jl_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading Julia code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/jl_loader/source/jl_loader.c b/source/loaders/jl_loader/source/jl_loader.c index 6819873849..dfee6cf030 100644 --- a/source/loaders/jl_loader/source/jl_loader.c +++ b/source/loaders/jl_loader/source/jl_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading Julia code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *jl_loader_print_info(void) { static const char jl_loader_info[] = "Julia Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef JL_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/jl_loader/source/jl_loader_impl.cpp b/source/loaders/jl_loader/source/jl_loader_impl.cpp index 9c9620e897..cb042d7113 100644 --- a/source/loaders/jl_loader/source/jl_loader_impl.cpp +++ b/source/loaders/jl_loader/source/jl_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading Julia code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/js_loader/CMakeLists.txt b/source/loaders/js_loader/CMakeLists.txt index e5a963fb09..c6e599df28 100644 --- a/source/loaders/js_loader/CMakeLists.txt +++ b/source/loaders/js_loader/CMakeLists.txt @@ -171,7 +171,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/js_loader/include/js_loader/js_loader.h b/source/loaders/js_loader/include/js_loader/js_loader.h index 7af1acf54b..7da9697a9a 100644 --- a/source/loaders/js_loader/include/js_loader/js_loader.h +++ b/source/loaders/js_loader/include/js_loader/js_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JS_LOADER_API loader_impl_interface js_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(js_loader_impl_interface_singleton); - JS_LOADER_API const char *js_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(js_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/js_loader/include/js_loader/js_loader_impl.h b/source/loaders/js_loader/include/js_loader/js_loader_impl.h index 78926f39e3..ce79543ebc 100644 --- a/source/loaders/js_loader/include/js_loader/js_loader_impl.h +++ b/source/loaders/js_loader/include/js_loader/js_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/js_loader/include/js_loader/js_loader_impl_guard.hpp b/source/loaders/js_loader/include/js_loader/js_loader_impl_guard.hpp index 5105ba6ba0..18198c69cd 100644 --- a/source/loaders/js_loader/include/js_loader/js_loader_impl_guard.hpp +++ b/source/loaders/js_loader/include/js_loader/js_loader_impl_guard.hpp @@ -3,7 +3,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/js_loader/source/js_loader.c b/source/loaders/js_loader/source/js_loader.c index eaf44404d9..4cb6c5c300 100644 --- a/source/loaders/js_loader/source/js_loader.c +++ b/source/loaders/js_loader/source/js_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *js_loader_print_info(void) { static const char js_loader_info[] = "Javascript Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef JS_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/js_loader/source/js_loader_impl.cpp b/source/loaders/js_loader/source/js_loader_impl.cpp index 845a4f5a0f..ccc79a8203 100644 --- a/source/loaders/js_loader/source/js_loader_impl.cpp +++ b/source/loaders/js_loader/source/js_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/js_loader/source/js_loader_impl_guard.cpp b/source/loaders/js_loader/source/js_loader_impl_guard.cpp index 0d7c199768..c3d4e82084 100644 --- a/source/loaders/js_loader/source/js_loader_impl_guard.cpp +++ b/source/loaders/js_loader/source/js_loader_impl_guard.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/jsm_loader/CMakeLists.txt b/source/loaders/jsm_loader/CMakeLists.txt index 3993e4b1fc..00266a3f26 100644 --- a/source/loaders/jsm_loader/CMakeLists.txt +++ b/source/loaders/jsm_loader/CMakeLists.txt @@ -169,7 +169,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h index b3d633549a..19f98f33db 100644 --- a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h +++ b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif JSM_LOADER_API loader_impl_interface jsm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(jsm_loader_impl_interface_singleton); - JSM_LOADER_API const char *jsm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(jsm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader_impl.h b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader_impl.h index 015e4830ae..6cc08d96da 100644 --- a/source/loaders/jsm_loader/include/jsm_loader/jsm_loader_impl.h +++ b/source/loaders/jsm_loader/include/jsm_loader/jsm_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/jsm_loader/source/jsm_loader.c b/source/loaders/jsm_loader/source/jsm_loader.c index 175269eff5..3725797aa4 100644 --- a/source/loaders/jsm_loader/source/jsm_loader.c +++ b/source/loaders/jsm_loader/source/jsm_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ const char *jsm_loader_print_info(void) { static const char jsm_loader_info[] = "Javascript Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef JSM_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/jsm_loader/source/jsm_loader_impl.cpp b/source/loaders/jsm_loader/source/jsm_loader_impl.cpp index 591f352f9c..f5ff0bddff 100644 --- a/source/loaders/jsm_loader/source/jsm_loader_impl.cpp +++ b/source/loaders/jsm_loader/source/jsm_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading javascript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/llvm_loader/CMakeLists.txt b/source/loaders/llvm_loader/CMakeLists.txt index 0b31d18fcf..954eba5d1d 100644 --- a/source/loaders/llvm_loader/CMakeLists.txt +++ b/source/loaders/llvm_loader/CMakeLists.txt @@ -169,7 +169,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h index db405edd83..b8cf75aca6 100644 --- a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h +++ b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading LLVM code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif LLVM_LOADER_API loader_impl_interface llvm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(llvm_loader_impl_interface_singleton); - LLVM_LOADER_API const char *llvm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(llvm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader_impl.h b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader_impl.h index d5949a9f15..b9637ae90c 100644 --- a/source/loaders/llvm_loader/include/llvm_loader/llvm_loader_impl.h +++ b/source/loaders/llvm_loader/include/llvm_loader/llvm_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading LLVM code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/llvm_loader/source/llvm_loader.c b/source/loaders/llvm_loader/source/llvm_loader.c index 0ffb622c45..4d3e8abd1f 100644 --- a/source/loaders/llvm_loader/source/llvm_loader.c +++ b/source/loaders/llvm_loader/source/llvm_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading LLVM code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *llvm_loader_print_info(void) { static const char llvm_loader_info[] = "LLVM Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef llvm_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/llvm_loader/source/llvm_loader_impl.cpp b/source/loaders/llvm_loader/source/llvm_loader_impl.cpp index bad187313e..f6bfd1d217 100644 --- a/source/loaders/llvm_loader/source/llvm_loader_impl.cpp +++ b/source/loaders/llvm_loader/source/llvm_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading LLVM code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/loader.json.in b/source/loaders/loader.json.in new file mode 100644 index 0000000000..713a30bbdd --- /dev/null +++ b/source/loaders/loader.json.in @@ -0,0 +1,6 @@ +{ + "search_paths": [ @LOADER_SEARCH_PATHS@ ], + "dependencies": { + @LOADER_DEPENDENCIES@ + } +} diff --git a/source/loaders/loaders.h.in b/source/loaders/loaders.h.in index d5d9dec8e3..f3b24b6edf 100644 --- a/source/loaders/loaders.h.in +++ b/source/loaders/loaders.h.in @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A library for loading executable code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/lua_loader/CMakeLists.txt b/source/loaders/lua_loader/CMakeLists.txt index bd1c7fd723..6816c8284e 100644 --- a/source/loaders/lua_loader/CMakeLists.txt +++ b/source/loaders/lua_loader/CMakeLists.txt @@ -167,7 +167,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/lua_loader/include/lua_loader/lua_loader.h b/source/loaders/lua_loader/include/lua_loader/lua_loader.h index f93ed53127..9179d5e50f 100644 --- a/source/loaders/lua_loader/include/lua_loader/lua_loader.h +++ b/source/loaders/lua_loader/include/lua_loader/lua_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading lua code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif LUA_LOADER_API loader_impl_interface lua_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(lua_loader_impl_interface_singleton); - LUA_LOADER_API const char *lua_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(lua_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/lua_loader/include/lua_loader/lua_loader_impl.h b/source/loaders/lua_loader/include/lua_loader/lua_loader_impl.h index 8861c9ba12..4c08972184 100644 --- a/source/loaders/lua_loader/include/lua_loader/lua_loader_impl.h +++ b/source/loaders/lua_loader/include/lua_loader/lua_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading lua code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/lua_loader/source/lua_loader.c b/source/loaders/lua_loader/source/lua_loader.c index fa56317ac9..b7cc942aae 100644 --- a/source/loaders/lua_loader/source/lua_loader.c +++ b/source/loaders/lua_loader/source/lua_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading lua code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *lua_loader_print_info(void) { static const char lua_loader_info[] = "Lua Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef LUA_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/lua_loader/source/lua_loader_impl.c b/source/loaders/lua_loader/source/lua_loader_impl.c index 63f8fdd660..58d89f20a5 100644 --- a/source/loaders/lua_loader/source/lua_loader_impl.c +++ b/source/loaders/lua_loader/source/lua_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading lua code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/CMakeLists.txt b/source/loaders/mock_loader/CMakeLists.txt index 72a8dfbcb0..6fb2c80dc3 100644 --- a/source/loaders/mock_loader/CMakeLists.txt +++ b/source/loaders/mock_loader/CMakeLists.txt @@ -154,7 +154,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader.h b/source/loaders/mock_loader/include/mock_loader/mock_loader.h index f92e7d1ddc..e2c17c49e9 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif MOCK_LOADER_API loader_impl_interface mock_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(mock_loader_impl_interface_singleton); - MOCK_LOADER_API const char *mock_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(mock_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_descriptor.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_descriptor.h index 5be7934722..9c48015f3b 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_descriptor.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_descriptor.h @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading mock code at run-time into a process. * diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_export.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_export.h index 3c474f8b17..6da9c5cb19 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_export.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_export.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_function.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_function.h index ee3c9e7bb6..8ea6d30316 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_function.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_function.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_function_interface.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_function_interface.h index ffcc0449a9..ece86e5fe6 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_function_interface.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_function_interface.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_handle.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_handle.h index 62322b4528..d0c7f23e11 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_handle.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_handle.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_impl.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_impl.h index 2d8992c737..e064db708d 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_impl.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_interface.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_interface.h index bb3dd7a47a..f8b9bb5ea0 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_interface.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_interface.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/include/mock_loader/mock_loader_print.h b/source/loaders/mock_loader/include/mock_loader/mock_loader_print.h index 09785d67ba..727d39ad78 100644 --- a/source/loaders/mock_loader/include/mock_loader/mock_loader_print.h +++ b/source/loaders/mock_loader/include/mock_loader/mock_loader_print.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/source/mock_loader.c b/source/loaders/mock_loader/source/mock_loader.c index 949ac2289e..6dddee2a32 100644 --- a/source/loaders/mock_loader/source/mock_loader.c +++ b/source/loaders/mock_loader/source/mock_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *mock_loader_print_info(void) { static const char mock_loader_info[] = "Mock Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef MOCK_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/mock_loader/source/mock_loader_descriptor.c b/source/loaders/mock_loader/source/mock_loader_descriptor.c index 74e8f76c2c..c88c90abb3 100644 --- a/source/loaders/mock_loader/source/mock_loader_descriptor.c +++ b/source/loaders/mock_loader/source/mock_loader_descriptor.c @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading mock code at run-time into a process. * diff --git a/source/loaders/mock_loader/source/mock_loader_export.c b/source/loaders/mock_loader/source/mock_loader_export.c index 7623d32852..e79fcfcda4 100644 --- a/source/loaders/mock_loader/source/mock_loader_export.c +++ b/source/loaders/mock_loader/source/mock_loader_export.c @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading mock code at run-time into a process. * diff --git a/source/loaders/mock_loader/source/mock_loader_function.c b/source/loaders/mock_loader/source/mock_loader_function.c index 7b2d8a64c9..f8a88864f0 100644 --- a/source/loaders/mock_loader/source/mock_loader_function.c +++ b/source/loaders/mock_loader/source/mock_loader_function.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/source/mock_loader_function_interface.c b/source/loaders/mock_loader/source/mock_loader_function_interface.c index 7310fa4153..92ead2583a 100644 --- a/source/loaders/mock_loader/source/mock_loader_function_interface.c +++ b/source/loaders/mock_loader/source/mock_loader_function_interface.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/source/mock_loader_handle.c b/source/loaders/mock_loader/source/mock_loader_handle.c index 8160483962..567ff46077 100644 --- a/source/loaders/mock_loader/source/mock_loader_handle.c +++ b/source/loaders/mock_loader/source/mock_loader_handle.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/source/mock_loader_impl.c b/source/loaders/mock_loader/source/mock_loader_impl.c index e63c7a1f11..7f8940e548 100644 --- a/source/loaders/mock_loader/source/mock_loader_impl.c +++ b/source/loaders/mock_loader/source/mock_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading mock code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/mock_loader/source/mock_loader_interface.c b/source/loaders/mock_loader/source/mock_loader_interface.c index 11368a61a9..0d24545f1b 100644 --- a/source/loaders/mock_loader/source/mock_loader_interface.c +++ b/source/loaders/mock_loader/source/mock_loader_interface.c @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading mock code at run-time into a process. * diff --git a/source/loaders/mock_loader/source/mock_loader_print.c b/source/loaders/mock_loader/source/mock_loader_print.c index c1a27cb27a..1539d5dbce 100644 --- a/source/loaders/mock_loader/source/mock_loader_print.c +++ b/source/loaders/mock_loader/source/mock_loader_print.c @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading mock code at run-time into a process. * @@ -14,7 +14,7 @@ const char *mock_loader_print_info(void) { static const char mock_loader_info[] = "Mock Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef MOCK_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/node_loader/CMakeLists.txt b/source/loaders/node_loader/CMakeLists.txt index 814f411f71..e76ed66f5e 100644 --- a/source/loaders/node_loader/CMakeLists.txt +++ b/source/loaders/node_loader/CMakeLists.txt @@ -22,6 +22,34 @@ if(NodeJS_LIBRARY_NAME_PATH AND WIN32) file(COPY "${NodeJS_LIBRARY_NAME_PATH}" DESTINATION ${PROJECT_OUTPUT_DIR}) endif() +# Runtime (pack NodeJS DLL in windows) +# TODO: https://cmake.org/cmake/help/latest/command/file.html#get-runtime-dependencies +# TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da +set(NodeJS_LIBRARY_DEVELOPMENT "${NodeJS_LIBRARY}") + +if(NodeJS_LIBRARY_NAME_PATH AND WIN32) + install(FILES + "${NodeJS_LIBRARY_NAME_PATH}" + DESTINATION ${INSTALL_LIB} + COMPONENT runtime + ) + + get_filename_component(NodeJS_LIBRARY_NAME "${NodeJS_LIBRARY_NAME_PATH}" NAME) + set(NodeJS_LIBRARY_DEVELOPMENT "${NodeJS_LIBRARY_NAME_PATH}") + set(NodeJS_LIBRARY_INSTALL "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/${NodeJS_LIBRARY_NAME}") +elseif(NodeJS_BUILD_FROM_SOURCE AND NOT WIN32) + install(FILES + "${NodeJS_LIBRARY}" + DESTINATION ${INSTALL_LIB} + COMPONENT runtime + ) + + get_filename_component(NodeJS_LIBRARY_NAME "${NodeJS_LIBRARY}" NAME) + set(NodeJS_LIBRARY_INSTALL "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/${NodeJS_LIBRARY_NAME}") +else() + set(NodeJS_LIBRARY_INSTALL "${NodeJS_LIBRARY}") +endif() + # # Plugin name and options # @@ -74,13 +102,6 @@ set(sources ${source_path}/node_loader_trampoline.cpp ) -if(WIN32 AND MSVC_VERSION GREATER_EQUAL 1200) - set(headers - ${headers} - ${include_path}/node_loader_win32_delay_load.h - ) -endif() - # Group source files set(header_group "Header Files (API)") set(source_group "Source Files") @@ -156,7 +177,10 @@ target_include_directories(${target} target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library - ${NodeJS_LIBRARY} # NodeJS library + + # Delay load for MSVC + $<$:${NodeJS_LIBRARY}> # NodeJS library + $<$:delayimp> PUBLIC ${DEFAULT_LIBRARIES} @@ -170,7 +194,9 @@ target_link_libraries(${target} target_compile_definitions(${target} PRIVATE - $<$:NODEJS_LIBRARY_NAME="${NodeJS_LIBRARY_NAME}"> + $<$>:_LARGEFILE_SOURCE> + $<$>:_FILE_OFFSET_BITS=64> + $<$,$>:_DARWIN_USE_64_BIT_INODE=1> PUBLIC $<$>:${target_upper}_STATIC_DEFINE> @@ -196,8 +222,10 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE + $<$,$>:-Wl,-undefined,dynamic_lookup> + $<$:/DELAYLOAD:${NodeJS_LIBRARY_NAME}> PUBLIC ${DEFAULT_LINKER_OPTIONS} @@ -225,19 +253,16 @@ install(TARGETS ${target} ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT dev ) -# Runtime (pack NodeJS DLL in windows) -# TODO: https://cmake.org/cmake/help/latest/command/file.html#get-runtime-dependencies -# TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da -if(NodeJS_LIBRARY_NAME_PATH AND WIN32) - install(FILES - "${NodeJS_LIBRARY_NAME_PATH}" - DESTINATION ${INSTALL_LIB} - COMPONENT runtime - ) -elseif(NodeJS_BUILD_FROM_SOURCE AND NOT WIN32) - install(FILES - "${NodeJS_LIBRARY}" - DESTINATION ${INSTALL_LIB} - COMPONENT runtime - ) -endif() +# +# Configuration +# + +# Development +loader_configuration_begin(node_loader) +loader_configuration_deps(node "${NodeJS_LIBRARY_DEVELOPMENT}") +loader_configuartion_end_development() + +# Install +loader_configuration_begin(node_loader) +loader_configuration_deps(node "${NodeJS_LIBRARY_INSTALL}") +loader_configuartion_end_install() diff --git a/source/loaders/node_loader/bootstrap/lib/bootstrap.js b/source/loaders/node_loader/bootstrap/lib/bootstrap.js index 5582ab48eb..8201b220a8 100644 --- a/source/loaders/node_loader/bootstrap/lib/bootstrap.js +++ b/source/loaders/node_loader/bootstrap/lib/bootstrap.js @@ -408,14 +408,20 @@ function node_loader_trampoline_await_future(trampoline) { }; } -module.exports = ((impl, ptr) => { +const startup = (impl, ptr, trampoline_exports) => { try { if (typeof impl === 'undefined' || typeof ptr === 'undefined') { - throw new Error('Process arguments (process.argv[2], process.argv[3]) not defined.'); + throw new Error('Bootstrap startup arguments impl or ptr are not defined.'); } // Get trampoline from list of linked bindings - const trampoline = process._linkedBinding('node_loader_trampoline_module'); + const trampoline = (() => { + if (trampoline_exports) { + return trampoline_exports; + } + + return process._linkedBinding('node_loader_trampoline_module'); + })(); const node_loader_ptr = trampoline.register(impl, ptr, { 'initialize': node_loader_trampoline_initialize, @@ -430,7 +436,21 @@ module.exports = ((impl, ptr) => { 'await_function': node_loader_trampoline_await_function(trampoline), 'await_future': node_loader_trampoline_await_future(trampoline), }); + + // This function must destroy all the loaders but + // delaying the NodeJS Loader library unloading + if (trampoline_exports) { + process.on('exit', () => trampoline.destroy(node_loader_ptr)); + } } catch (ex) { console.log('Exception in bootstrap.js trampoline initialization:', ex); } +}; + +module.exports = ((impl, ptr) => { + if (impl === undefined || ptr === undefined) { + return startup; + } else { + return startup(impl, ptr); + } })(process.argv[2], process.argv[3]); diff --git a/source/loaders/node_loader/include/node_loader/node_loader.h b/source/loaders/node_loader/include/node_loader/node_loader.h index 8660376395..fc9af4c427 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader.h +++ b/source/loaders/node_loader/include/node_loader/node_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif NODE_LOADER_API loader_impl_interface node_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(node_loader_impl_interface_singleton); - NODE_LOADER_API const char *node_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(node_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/node_loader/include/node_loader/node_loader_bootstrap.h b/source/loaders/node_loader/include/node_loader/node_loader_bootstrap.h index 58e51d9040..1178d14738 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader_bootstrap.h +++ b/source/loaders/node_loader/include/node_loader/node_loader_bootstrap.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/node_loader/include/node_loader/node_loader_impl.h b/source/loaders/node_loader/include/node_loader/node_loader_impl.h index 6aa1f34488..ee424c9b30 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader_impl.h +++ b/source/loaders/node_loader/include/node_loader/node_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,9 @@ NODE_LOADER_NO_EXPORT void node_loader_impl_destroy_safe_impl(loader_impl_node n NODE_LOADER_NO_EXPORT void node_loader_impl_print_handles(loader_impl_node node_impl); -NODE_LOADER_NO_EXPORT int64_t node_loader_impl_user_async_handles_count(loader_impl_node node_impl); +NODE_LOADER_NO_EXPORT uint64_t node_loader_impl_user_async_handles_count(loader_impl_node node_impl); + +NODE_LOADER_NO_EXPORT napi_value node_loader_impl_register_bootstrap_startup(loader_impl_node node_impl, napi_env env); #ifdef __cplusplus } diff --git a/source/loaders/node_loader/include/node_loader/node_loader_port.h b/source/loaders/node_loader/include/node_loader/node_loader_port.h index effd3f06a9..0555f12471 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader_port.h +++ b/source/loaders/node_loader/include/node_loader/node_loader_port.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/node_loader/include/node_loader/node_loader_trampoline.h b/source/loaders/node_loader/include/node_loader/node_loader_trampoline.h index 228d6f5c6b..09c4ec6a32 100644 --- a/source/loaders/node_loader/include/node_loader/node_loader_trampoline.h +++ b/source/loaders/node_loader/include/node_loader/node_loader_trampoline.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,8 @@ typedef void *(*node_loader_trampoline_register_ptr)(void *, void *, void *); NODE_LOADER_NO_EXPORT napi_value node_loader_trampoline_initialize(napi_env env, napi_value exports); +NODE_LOADER_NO_EXPORT napi_value node_loader_trampoline_initialize_object(napi_env env); + #ifdef __cplusplus } #endif diff --git a/source/loaders/node_loader/include/node_loader/node_loader_win32_delay_load.h b/source/loaders/node_loader/include/node_loader/node_loader_win32_delay_load.h deleted file mode 100644 index 73fcb6f57d..0000000000 --- a/source/loaders/node_loader/include/node_loader/node_loader_win32_delay_load.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Loader Library by Parra Studios - * A plugin for loading nodejs code at run-time into a process. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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. - * - */ - -/* -- Headers -- */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include -#include - -inline void *node_loader_hook_import_address_table(const char *module_name, const char *function_name, void *hook) -{ - LPVOID image_base = GetModuleHandle(module_name); - PIMAGE_DOS_HEADER dos_headers = (PIMAGE_DOS_HEADER)image_base; - - if (dos_headers->e_magic != IMAGE_DOS_SIGNATURE) - { - return NULL; - } - - PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS)((DWORD_PTR)image_base + dos_headers->e_lfanew); - - if (nt_headers->Signature != IMAGE_NT_SIGNATURE) - { - return NULL; - } - - IMAGE_DATA_DIRECTORY *imports_directory = &nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; - - if (imports_directory->Size == 0 || imports_directory->VirtualAddress == 0) - { - return NULL; - } - - PIMAGE_IMPORT_DESCRIPTOR import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)(imports_directory->VirtualAddress + (DWORD_PTR)image_base); - - for (; import_descriptor->FirstThunk != NULL; ++import_descriptor) - { - PIMAGE_THUNK_DATA original_first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)image_base + import_descriptor->OriginalFirstThunk); // Image thunk data names - PIMAGE_THUNK_DATA first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)image_base + import_descriptor->FirstThunk); // Image thunk data address - - for (; original_first_thunk->u1.AddressOfData != NULL; ++original_first_thunk, ++first_thunk) - { - if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) - { - PIMAGE_IMPORT_BY_NAME func = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)image_base + original_first_thunk->u1.AddressOfData); - - if (strcmp(func->Name, function_name) == 0) - { - LPVOID original_address = (LPVOID)(first_thunk->u1.Function); - LPVOID import_func_load_address = (LPVOID)(&first_thunk->u1.Function); - DWORD old_page_protect, unused_old_page_protect; - - VirtualProtect(import_func_load_address, sizeof(void *), PAGE_EXECUTE_READWRITE, &old_page_protect); - - memcpy(import_func_load_address, &hook, sizeof(hook)); - - VirtualProtect(import_func_load_address, sizeof(void *), old_page_protect, &unused_old_page_protect); - - return (void *)original_address; - } - } - } - } - - return NULL; -} diff --git a/source/loaders/node_loader/source/node_loader.c b/source/loaders/node_loader/source/node_loader.c index e768a8f89a..96b5b37bf8 100644 --- a/source/loaders/node_loader/source/node_loader.c +++ b/source/loaders/node_loader/source/node_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading nodejs code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *node_loader_print_info(void) { static const char node_loader_info[] = "Javascript Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef JS_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/node_loader/source/node_loader_impl.cpp b/source/loaders/node_loader/source/node_loader_impl.cpp index bfe6e90c47..b493d19646 100644 --- a/source/loaders/node_loader/source/node_loader_impl.cpp +++ b/source/loaders/node_loader/source/node_loader_impl.cpp @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading nodejs code at run-time into a process. * @@ -49,7 +49,7 @@ extern char **environ; #include #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1200) - #include + #include /* Required for the DelayLoad hook interposition, solves bug of NodeJS extensions requiring node.exe instead of node.dll*/ #include @@ -77,9 +77,6 @@ extern char **environ; #include #include -#include -#include -#include #include #include @@ -181,8 +178,8 @@ union loader_impl_handle_safe_cast typedef struct loader_impl_node_function_type { - loader_impl_node node_impl; loader_impl impl; + loader_impl_node node_impl; napi_ref func_ref; napi_value *argv; @@ -190,6 +187,7 @@ typedef struct loader_impl_node_function_type typedef struct loader_impl_node_future_type { + loader_impl impl; loader_impl_node node_impl; napi_ref promise_ref; @@ -553,6 +551,118 @@ struct loader_impl_async_destroy_safe_type node_impl(node_impl), has_finished(false) {} }; +static void *node_loader_impl_register(void *node_impl_ptr, void *env_ptr, void *function_table_object_ptr); + +typedef struct node_loader_impl_startup_args_type +{ + /* Executable path */ + portability_executable_path_str exe_path_str = { 0 }; + portability_executable_path_length length = 0; + size_t exe_path_str_size = 0, exe_path_str_offset = 0; + + /* Bootstrap path */ + loader_path bootstrap_path_str = { 0 }; + size_t bootstrap_path_str_size = 0; + + /* The node_impl pointer */ + char *node_impl_ptr_str = nullptr; + size_t node_impl_ptr_str_size = 0; + + /* The register function pointer */ + char *register_ptr_str = nullptr; + size_t register_ptr_str_size = 0; + + node_loader_impl_startup_args_type() {} + + ~node_loader_impl_startup_args_type() + { + if (node_impl_ptr_str != nullptr) + { + delete[] node_impl_ptr_str; + } + + if (register_ptr_str != nullptr) + { + delete[] register_ptr_str; + } + } + + int initialize(loader_impl_node node_impl, configuration config) + { + /* Get the executable */ + if (portability_executable_path(exe_path_str, &length) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Node loader failed to retrieve the executable path (%s)", exe_path_str); + return 1; + } + + for (size_t iterator = 0; iterator <= (size_t)length; ++iterator) + { +#if defined(WIN32) || defined(_WIN32) + if (exe_path_str[iterator] == '\\') +#else + if (exe_path_str[iterator] == '/') +#endif + { + exe_path_str_offset = iterator + 1; + } + } + + exe_path_str_size = (size_t)length - exe_path_str_offset + 1; + + /* Get the bootstrap.js path */ + static const char bootstrap_file_str[] = "bootstrap.js"; + + if (node_loader_impl_bootstrap_path(bootstrap_file_str, sizeof(bootstrap_file_str) - 1, config, bootstrap_path_str, &bootstrap_path_str_size) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "LOADER_LIBRARY_PATH environment variable or loader_library_path field in configuration is not defined, bootstrap.js cannot be found"); + return 1; + } + + /* Get node impl pointer */ + ssize_t node_impl_ptr_length = snprintf(NULL, 0, "%" PRIxPTR, (uintptr_t)(node_impl)); + + if (node_impl_ptr_length <= 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid node impl pointer length in NodeJS thread"); + return 1; + } + + node_impl_ptr_str_size = static_cast(node_impl_ptr_length + 1); + node_impl_ptr_str = new char[node_impl_ptr_str_size]; + + if (node_impl_ptr_str == nullptr) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid node impl pointer initialization in NodeJS thread"); + return 1; + } + + snprintf(node_impl_ptr_str, node_impl_ptr_str_size, "%" PRIxPTR, (uintptr_t)(node_impl)); + + /* Get register pointer */ + ssize_t register_ptr_length = snprintf(NULL, 0, "%" PRIxPTR, (uintptr_t)(&node_loader_impl_register)); + + if (register_ptr_length <= 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid register pointer length in NodeJS thread"); + return 1; + } + + register_ptr_str_size = static_cast(register_ptr_length + 1); + register_ptr_str = new char[register_ptr_str_size]; + + if (register_ptr_str == nullptr) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid register pointer initialization in NodeJS thread"); + return 1; + } + + snprintf(register_ptr_str, register_ptr_str_size, "%" PRIxPTR, (uintptr_t)(&node_loader_impl_register)); + + return 0; + } +} * node_loader_impl_startup_args; + struct loader_impl_node_type { /* TODO: The current implementation may not support multi-isolate environments. We should test it. */ @@ -575,6 +685,7 @@ struct loader_impl_node_type uv_thread_t thread; uv_loop_t *thread_loop; + std::vector *delayed_execution_paths; uv_mutex_t mutex; uv_cond_t cond; @@ -588,14 +699,14 @@ struct loader_impl_node_type uv_thread_t thread_log_id; #endif + node_loader_impl_startup_args_type thread_data; int result; - const char *error_message; /* TODO: This implementation won't work for multi-isolate environments. We should test it. */ std::thread::id js_thread_id; - int64_t base_active_handles; - std::atomic_int64_t extra_active_handles; + uint64_t base_active_handles; + std::atomic_uint64_t extra_active_handles; uv_prepare_t destroy_prepare; uv_check_t destroy_check; std::atomic_bool event_loop_empty; @@ -688,13 +799,6 @@ typedef struct loader_impl_async_func_await_trampoline_type } * loader_impl_async_func_await_trampoline; -typedef struct loader_impl_thread_type -{ - loader_impl_node node_impl; - configuration config; - -} * loader_impl_thread; - typedef struct loader_impl_napi_to_value_callback_closure_type { value func; @@ -754,11 +858,11 @@ static void node_loader_impl_handle_promise_safe(napi_env env, loader_impl_async static void node_loader_impl_destroy_safe(napi_env env, loader_impl_async_destroy_safe_type *destroy_safe); +static void node_loader_impl_destroy_hook(loader_impl_node node_impl); + static char *node_loader_impl_get_property_as_char(napi_env env, napi_value obj, const char *prop); /* Loader */ -static void *node_loader_impl_register(void *node_impl_ptr, void *env_ptr, void *function_table_object_ptr); - static void node_loader_impl_thread(void *data); #ifdef __ANDROID__ @@ -771,7 +875,7 @@ static void node_loader_impl_thread_log(void *data); static void node_loader_impl_walk_async_handles_count(uv_handle_t *handle, void *arg); #endif -static int64_t node_loader_impl_async_handles_count(loader_impl_node node_impl); +static uint64_t node_loader_impl_async_handles_count(loader_impl_node node_impl); static void node_loader_impl_try_destroy(loader_impl_node node_impl); @@ -779,43 +883,72 @@ static void node_loader_impl_try_destroy(loader_impl_node node_impl); /* Required for the DelayLoad hook interposition, solves bug of NodeJS extensions requiring node.exe instead of node.dll */ static HMODULE node_loader_node_dll_handle = NULL; static HMODULE (*get_module_handle_a_ptr)(_In_opt_ LPCSTR) = NULL; /* TODO: Implement W version too? */ +static detour_handle node_module_handle_a_handle = NULL; #endif /* -- Methods -- */ +#if NODE_MAJOR_VERSION >= 12 + #define node_loader_impl_register_module_id node::ModuleFlags::kLinked | 0x08 /* NM_F_DELETEME */ +#else + #define node_loader_impl_register_module_id 0x02 | 0x08 /* NM_F_LINKED | NM_F_DELETEME */ +#endif + #if 1 // NODE_MAJOR_VERSION < 18 - #if NODE_MAJOR_VERSION >= 12 - #define node_loader_impl_register_module_id node::ModuleFlags::kLinked | 0x08 /* NM_F_DELETEME */ - #else - #define node_loader_impl_register_module_id 0x02 | 0x08 /* NM_F_LINKED | NM_F_DELETEME */ - #endif + #define node_loader_impl_register_binding(module) \ + napi_module_register(&module) +#else + // TODO: This won't work, this must be run after NodeJS has initialized and passing the environment + #define node_loader_impl_register_binding(module) \ + AddLinkedBinding(nullptr, module) +#endif - #define node_loader_impl_register_module(name, fn) \ - do \ - { \ - static napi_module node_loader_module = { \ - NAPI_MODULE_VERSION, \ - node_loader_impl_register_module_id, \ - __FILE__, \ - fn, \ - name, \ - NULL, \ - { 0 } \ - }; \ - napi_module_register(&node_loader_module); \ - } while (0) +#define node_loader_impl_register_module(name, fn) \ + do \ + { \ + static napi_module node_loader_module = { \ + NAPI_MODULE_VERSION, \ + node_loader_impl_register_module_id, \ + __FILE__, \ + fn, \ + name, \ + NULL, \ + { 0 } \ + }; \ + node_loader_impl_register_binding(node_loader_module); \ + } while (0) void node_loader_impl_register_linked_bindings() { + /* + * For now napi_module_register won't be deprecated: https://github.com/nodejs/node/issues/56153 + * If this changes, we can investigate the alternative approach. + */ +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable : 4996) +#elif defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + /* Initialize Node Loader Trampoline */ node_loader_impl_register_module("node_loader_trampoline_module", node_loader_trampoline_initialize); /* Initialize Node Loader Port */ node_loader_impl_register_module("node_loader_port_module", node_loader_port_initialize); -} -#else -// TODO: New register implementation + +#if defined(_MSC_VER) + #pragma warning(pop) +#elif defined(__clang__) + #pragma clang diagnostic pop +#elif defined(__GNUC__) + #pragma GCC diagnostic pop #endif +} void node_loader_impl_exception(napi_env env, napi_status status) { @@ -1225,6 +1358,7 @@ value node_loader_impl_napi_to_value(loader_impl_node node_impl, napi_env env, n /* Create reference to promise */ node_future->node_impl = node_impl; + node_future->impl = node_impl->impl; status = napi_create_reference(env, v, 1, &node_future->promise_ref); @@ -1308,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; @@ -1501,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); @@ -1711,7 +1841,7 @@ void function_node_interface_destroy(function func, function_impl impl) return; } - if (loader_is_destroyed(node_func->node_impl->impl) != 0) + if (loader_is_destroyed(node_func->impl) != 0) { loader_impl_node node_impl = node_func->node_impl; loader_impl_async_func_destroy_safe_type func_destroy_safe(node_impl, node_func); @@ -1792,7 +1922,7 @@ void future_node_interface_destroy(future f, future_impl impl) return; } - if (loader_is_destroyed(node_future->node_impl->impl) != 0) + if (loader_is_destroyed(node_future->impl) != 0) { loader_impl_node node_impl = node_future->node_impl; loader_impl_async_future_delete_safe_type future_delete_safe(node_impl, f, node_future); @@ -3565,212 +3695,112 @@ void *node_loader_impl_register(void *node_impl_ptr, void *env_ptr, void *functi /* On Windows, hook node extension loading mechanism in order to patch extensions linked to node.exe */ #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1200) - node_loader_node_dll_handle = GetModuleHandle(NODEJS_LIBRARY_NAME); - get_module_handle_a_ptr = (HMODULE(*)(_In_opt_ LPCSTR))node_loader_hook_import_address_table("kernel32.dll", "GetModuleHandleA", &get_module_handle_a_hook); -#endif - - /* Close scope */ - status = napi_close_handle_scope(env, handle_scope); - - node_loader_impl_exception(env, status); - - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); - - uv_mutex_unlock(&node_impl->mutex); - - /* TODO: Return */ - return NULL; -} - -void node_loader_impl_thread(void *data) -{ - loader_impl_thread thread_data = static_cast(data); - loader_impl_node node_impl = thread_data->node_impl; - configuration config = thread_data->config; - - /* Lock node implementation mutex */ - uv_mutex_lock(&node_impl->mutex); - - /* TODO: Reimplement from here to ... */ - portability_executable_path_str exe_path_str = { 0 }; - portability_executable_path_length length = 0; - size_t exe_path_str_size = 0, exe_path_str_offset = 0; - - if (portability_executable_path(exe_path_str, &length) != 0) { - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Node loader failed to retrieve the executable path"; - - /* TODO: Make logs thread safe */ - /* log_write("metacall", LOG_LEVEL_ERROR, "Node loader failed to retrieve the executable path (%s)", exe_path_str); */ + /* As the library handle is correctly resolved here, either to executable, library of the executable, + or the loader dependency we can directly get the handle of this dependency */ + dynlink node_library = loader_impl_dependency(node_impl->impl, "node"); - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); - - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); - - return; - } + node_loader_node_dll_handle = static_cast(dynlink_get_impl(node_library)); - for (size_t iterator = 0; iterator <= (size_t)length; ++iterator) - { -#if defined(WIN32) || defined(_WIN32) - if (exe_path_str[iterator] == '\\') -#else - if (exe_path_str[iterator] == '/') -#endif + if (node_loader_node_dll_handle == NULL) { - exe_path_str_offset = iterator + 1; + napi_throw_error(env, nullptr, "Failed to initialize the hooking against node extensions load mechanism"); + return NULL; } - } - exe_path_str_size = (size_t)length - exe_path_str_offset + 1; + detour d = detour_create(metacall_detour()); - /* Get the boostrap path */ - static const char bootstrap_file_str[] = "bootstrap.js"; - loader_path bootstrap_path_str = { 0 }; - size_t bootstrap_path_str_size = 0; - - if (node_loader_impl_bootstrap_path(bootstrap_file_str, sizeof(bootstrap_file_str) - 1, config, bootstrap_path_str, &bootstrap_path_str_size) != 0) - { - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "LOADER_LIBRARY_PATH environment variable or loader_library_path field in configuration is not defined, bootstrap.js cannot be found"; + node_module_handle_a_handle = detour_load_file(d, "kernel32.dll"); - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); - - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); - - return; - } - - /* Get node impl pointer */ - char *node_impl_ptr_str; - size_t node_impl_ptr_str_size; - - ssize_t node_impl_ptr_length = snprintf(NULL, 0, "%p", (void *)node_impl); - - if (node_impl_ptr_length <= 0) - { - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Invalid node impl pointer length in NodeJS thread"; - - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); + if (node_module_handle_a_handle == NULL) + { + napi_throw_type_error(env, nullptr, "Invalid creation of the detour handle for hooking node extension load mechanism"); + } + else + { + typedef HMODULE (*get_module_handle_a_type)(_In_opt_ LPCSTR); - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); + union + { + get_module_handle_a_type *trampoline; + void (**ptr)(void); + } cast = { &get_module_handle_a_ptr }; - return; + if (detour_replace(d, node_module_handle_a_handle, "GetModuleHandleA", (void (*)(void))(&get_module_handle_a_hook), cast.ptr) != 0) + { + napi_throw_type_error(env, nullptr, "Invalid replacement of GetModuleHandle for hooking node extension load mechanism"); + } + } } +#endif - node_impl_ptr_str_size = static_cast(node_impl_ptr_length + 1); - node_impl_ptr_str = new char[node_impl_ptr_str_size]; - - if (node_impl_ptr_str == nullptr) + /* On host mode, register delayed paths */ + if (node_impl->delayed_execution_paths != nullptr) { - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Invalid node impl pointer initialization in NodeJS thread"; - - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); - - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); - - return; - } + std::vector *paths = node_impl->delayed_execution_paths; - snprintf(node_impl_ptr_str, node_impl_ptr_str_size, "%p", (void *)node_impl); + node_impl->delayed_execution_paths = nullptr; - /* Get register pointer */ - char *register_ptr_str; - size_t register_ptr_str_size; - ssize_t register_ptr_length = snprintf(NULL, 0, "%p", (void *)&node_loader_impl_register); - - if (register_ptr_length <= 0) - { - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Invalid register pointer length in NodeJS thread"; - - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); + for (const std::string &path : *paths) + { + if (node_loader_impl_execution_path(node_impl->impl, path.c_str()) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to register a delayed execution path: %s", path.c_str()); + } + } - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); + delete paths; - return; + /* Trigger destroy hook */ + node_loader_impl_destroy_hook(node_impl); } - register_ptr_str_size = static_cast(register_ptr_length + 1); - register_ptr_str = new char[register_ptr_str_size]; + /* Close scope */ + status = napi_close_handle_scope(env, handle_scope); - if (register_ptr_str == nullptr) - { - delete[] node_impl_ptr_str; + node_loader_impl_exception(env, status); - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Invalid register pointer initialization in NodeJS thread"; + /* Signal start condition */ + uv_cond_signal(&node_impl->cond); - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); + uv_mutex_unlock(&node_impl->mutex); - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); + /* TODO: Return */ + return NULL; +} - return; - } +void node_loader_impl_thread(void *data) +{ + loader_impl_node node_impl = static_cast(data); + node_loader_impl_startup_args args = &node_impl->thread_data; - snprintf(register_ptr_str, register_ptr_str_size, "%p", (void *)&node_loader_impl_register); + /* Lock node implementation mutex */ + uv_mutex_lock(&node_impl->mutex); /* Define argv_str contigously allocated with: executable name, bootstrap file, node impl pointer and register pointer */ - size_t argv_str_size = exe_path_str_size + bootstrap_path_str_size + node_impl_ptr_str_size + register_ptr_str_size; + size_t argv_str_size = args->exe_path_str_size + args->bootstrap_path_str_size + args->node_impl_ptr_str_size + args->register_ptr_str_size; char *argv_str = new char[argv_str_size]; - if (argv_str == nullptr) - { - delete[] node_impl_ptr_str; - delete[] register_ptr_str; - - /* Report error (TODO: Implement it with thread safe logs) */ - node_impl->error_message = "Invalid argv initialization in NodeJS thread"; - - /* Signal start condition */ - uv_cond_signal(&node_impl->cond); - - /* Unlock node implementation mutex */ - uv_mutex_unlock(&node_impl->mutex); - - return; - } - /* Initialize the argv string memory */ memset(argv_str, 0, sizeof(char) * argv_str_size); - memcpy(&argv_str[0], &exe_path_str[exe_path_str_offset], exe_path_str_size); - memcpy(&argv_str[exe_path_str_size], bootstrap_path_str, bootstrap_path_str_size); - memcpy(&argv_str[exe_path_str_size + bootstrap_path_str_size], node_impl_ptr_str, node_impl_ptr_str_size); - memcpy(&argv_str[exe_path_str_size + bootstrap_path_str_size + node_impl_ptr_str_size], register_ptr_str, register_ptr_str_size); - - delete[] node_impl_ptr_str; - delete[] register_ptr_str; + memcpy(&argv_str[0], &args->exe_path_str[args->exe_path_str_offset], args->exe_path_str_size); + memcpy(&argv_str[args->exe_path_str_size], args->bootstrap_path_str, args->bootstrap_path_str_size); + memcpy(&argv_str[args->exe_path_str_size + args->bootstrap_path_str_size], args->node_impl_ptr_str, args->node_impl_ptr_str_size); + memcpy(&argv_str[args->exe_path_str_size + args->bootstrap_path_str_size + args->node_impl_ptr_str_size], args->register_ptr_str, args->register_ptr_str_size); /* Define argv */ char *argv[] = { &argv_str[0], - &argv_str[exe_path_str_size], - &argv_str[exe_path_str_size + bootstrap_path_str_size], - &argv_str[exe_path_str_size + bootstrap_path_str_size + node_impl_ptr_str_size], + &argv_str[args->exe_path_str_size], + &argv_str[args->exe_path_str_size + args->bootstrap_path_str_size], + &argv_str[args->exe_path_str_size + args->bootstrap_path_str_size + args->node_impl_ptr_str_size], NULL }; int argc = 4; - /* TODO: ... reimplement until here */ - + /* Initialize current thread event loop */ node_impl->thread_loop = uv_default_loop(); #if defined(__POSIX__) @@ -3806,15 +3836,12 @@ void node_loader_impl_thread(void *data) #endif */ - // #if NODE_MAJOR_VERSION < 18 + /* Register bindings */ node_loader_impl_register_linked_bindings(); - // #endif /* Unlock node implementation mutex */ uv_mutex_unlock(&node_impl->mutex); - /* Register bindings for versions older than 18 */ - /* Start NodeJS runtime */ int result = node::Start(argc, reinterpret_cast(argv)); @@ -3911,7 +3938,6 @@ loader_impl_data node_loader_impl_initialize(loader_impl impl, configuration con /* Initialize execution result */ node_impl->result = 1; - node_impl->error_message = NULL; /* Initialize the reference to the loader so we can use it on the destruction */ node_impl->impl = impl; @@ -3932,69 +3958,85 @@ loader_impl_data node_loader_impl_initialize(loader_impl impl, configuration con } #endif - struct loader_impl_thread_type thread_data = { - node_impl, - config - }; - - /* Create NodeJS thread */ - if (uv_thread_create(&node_impl->thread, node_loader_impl_thread, &thread_data) != 0) + if (node_impl->thread_data.initialize(node_impl, config) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid NodeJS Thread creation"); - - /* TODO: Clear resources */ + log_write("metacall", LOG_LEVEL_ERROR, "Invalid startup arguments creation"); delete node_impl; return NULL; } - /* Wait until start has been launch */ - uv_mutex_lock(&node_impl->mutex); + if (loader_impl_get_option_host(impl) == 0) + { + /* Create NodeJS thread */ + if (uv_thread_create(&node_impl->thread, node_loader_impl_thread, node_impl) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid NodeJS Thread creation"); - uv_cond_wait(&node_impl->cond, &node_impl->mutex); + /* TODO: Clear resources */ - if (node_impl->error_message != NULL) - { - uv_mutex_unlock(&node_impl->mutex); + delete node_impl; - /* TODO: Remove this when implementing thread safe */ - log_write("metacall", LOG_LEVEL_ERROR, node_impl->error_message); + return NULL; + } - return NULL; - } + /* Wait until start has been launch */ + uv_mutex_lock(&node_impl->mutex); - uv_mutex_unlock(&node_impl->mutex); + uv_cond_wait(&node_impl->cond, &node_impl->mutex); - /* Call initialize function with thread safe */ - { - loader_impl_async_initialize_safe_type initialize_safe(node_impl, value_to_string(configuration_value(config, "loader_library_path"))); - int result = 1; + uv_mutex_unlock(&node_impl->mutex); - /* Check if we are in the JavaScript thread */ - if (node_impl->js_thread_id == std::this_thread::get_id()) + /* Call initialize function with thread safe (only when not using host) */ { - /* We are already in the V8 thread, we can call safely */ - node_loader_impl_initialize_safe(node_impl->env, &initialize_safe); + loader_impl_async_initialize_safe_type initialize_safe(node_impl, value_to_string(configuration_value(config, "loader_library_path"))); + int result = 1; - /* Set up return of the function call */ - result = initialize_safe.result; - } - else - { - /* Submit the task to the async queue */ - loader_impl_threadsafe_invoke_type invoke(node_impl->threadsafe_initialize, initialize_safe); + /* Check if we are in the JavaScript thread */ + if (node_impl->js_thread_id == std::this_thread::get_id()) + { + /* We are already in the V8 thread, we can call safely */ + node_loader_impl_initialize_safe(node_impl->env, &initialize_safe); + + /* Set up return of the function call */ + result = initialize_safe.result; + } + else + { + /* Submit the task to the async queue */ + loader_impl_threadsafe_invoke_type invoke(node_impl->threadsafe_initialize, initialize_safe); - /* Set up return of the function call */ - result = initialize_safe.result; + /* Set up return of the function call */ + result = initialize_safe.result; + } + + if (result != 0) + { + /* TODO: Implement better error message */ + log_write("metacall", LOG_LEVEL_ERROR, "Call to initialization function node_loader_impl_async_initialize_safe failed"); + + /* TODO: Handle properly the error */ + } } - if (result != 0) - { - /* TODO: Implement better error message */ - log_write("metacall", LOG_LEVEL_ERROR, "Call to initialization function node_loader_impl_async_initialize_safe failed"); + /* Initialize delayed execution paths to null, they are only used in host mode */ + node_impl->delayed_execution_paths = nullptr; + } + else + { + /* Initialize current thread event loop */ + node_impl->thread_loop = uv_default_loop(); + + /* Initialize delayed execution paths for register them once it has been initialized */ + node_impl->delayed_execution_paths = new std::vector(); - /* TODO: Handle properly the error */ + /* Result will never be defined properly */ + node_impl->result = 0; + + if (metacall_link_register_loader(impl, "node", "napi_register_module_v1", (void (*)(void))(&node_loader_port_initialize)) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Node Loader failed to hook napi_register_module_v1"); } } @@ -4004,6 +4046,40 @@ loader_impl_data node_loader_impl_initialize(loader_impl impl, configuration con return node_impl; } +napi_value node_loader_impl_register_bootstrap_startup(loader_impl_node node_impl, napi_env env) +{ + node_loader_impl_startup_args args = &node_impl->thread_data; + napi_value argv[4], v; + napi_status status; + + status = napi_create_array_with_length(env, 4, &v); + node_loader_impl_exception(env, status); + + /* Convert bootstrap.js path to N-API value */ + status = napi_create_string_utf8(env, args->bootstrap_path_str, args->bootstrap_path_str_size - 1, &argv[0]); + node_loader_impl_exception(env, status); + + /* Convert node impl to N-API value */ + status = napi_create_string_utf8(env, args->node_impl_ptr_str, args->node_impl_ptr_str_size - 1, &argv[1]); + node_loader_impl_exception(env, status); + + /* Convert register to N-API value */ + status = napi_create_string_utf8(env, args->register_ptr_str, args->register_ptr_str_size - 1, &argv[2]); + node_loader_impl_exception(env, status); + + /* Create trampoline exports */ + argv[3] = node_loader_trampoline_initialize_object(env); + + /* Set the values */ + for (uint32_t iterator = 0; iterator < 4; ++iterator) + { + status = napi_set_element(env, v, iterator, argv[iterator]); + node_loader_impl_exception(env, status); + } + + return v; +} + int node_loader_impl_execution_path(loader_impl impl, const loader_path path) { loader_impl_node node_impl = static_cast(loader_impl_get(impl)); @@ -4013,6 +4089,15 @@ int node_loader_impl_execution_path(loader_impl impl, const loader_path path) return 1; } + /* When using host mode, the paths are registered before NodeJS is properly initialized, + * delay the execution path registration until it is properly registered + */ + if (node_impl->delayed_execution_paths != nullptr) + { + node_impl->delayed_execution_paths->push_back(path); + return 0; + } + loader_impl_async_execution_path_safe_type execution_path_safe(node_impl, static_cast(path)); /* Check if we are in the JavaScript thread */ @@ -4235,6 +4320,32 @@ napi_value node_loader_impl_promise_await(loader_impl_node node_impl, napi_env e return promise; } +static void node_loader_impl_destroy_close_cb(loader_impl_node node_impl, napi_env env) +{ + if (--node_impl->extra_active_handles == 0) + { + if (loader_impl_get_option_host(node_impl->impl) == 0) + { + node_loader_impl_try_destroy(node_impl); + } + else + { + node_impl->threadsafe_initialize.abort(env); + node_impl->threadsafe_execution_path.abort(env); + node_impl->threadsafe_load_from_file.abort(env); + node_impl->threadsafe_load_from_memory.abort(env); + node_impl->threadsafe_clear.abort(env); + node_impl->threadsafe_discover.abort(env); + node_impl->threadsafe_func_call.abort(env); + node_impl->threadsafe_func_await.abort(env); + node_impl->threadsafe_func_destroy.abort(env); + node_impl->threadsafe_future_await.abort(env); + node_impl->threadsafe_future_delete.abort(env); + node_impl->threadsafe_destroy.abort(env); + } + } +} + #define container_of(ptr, type, member) \ (type *)((char *)(ptr) - (char *)&((type *)0)->member) @@ -4243,10 +4354,7 @@ static void node_loader_impl_destroy_prepare_close_cb(uv_handle_t *handle) uv_prepare_t *prepare = (uv_prepare_t *)handle; loader_impl_node node_impl = container_of(prepare, struct loader_impl_node_type, destroy_prepare); - if (--node_impl->extra_active_handles == 0) - { - node_loader_impl_try_destroy(node_impl); - } + node_loader_impl_destroy_close_cb(node_impl, node_impl->env); } static void node_loader_impl_destroy_check_close_cb(uv_handle_t *handle) @@ -4254,10 +4362,7 @@ static void node_loader_impl_destroy_check_close_cb(uv_handle_t *handle) uv_check_t *check = (uv_check_t *)handle; loader_impl_node node_impl = container_of(check, struct loader_impl_node_type, destroy_check); - if (--node_impl->extra_active_handles == 0) - { - node_loader_impl_try_destroy(node_impl); - } + node_loader_impl_destroy_close_cb(node_impl, node_impl->env); } static void node_loader_impl_destroy_cb(loader_impl_node node_impl) @@ -4266,7 +4371,7 @@ static void node_loader_impl_destroy_cb(loader_impl_node node_impl) node_loader_impl_print_handles(node_impl); #endif - if (node_impl->event_loop_empty.load() == false && node_loader_impl_user_async_handles_count(node_impl) <= 0) + if (node_impl->event_loop_empty.load() == false && node_loader_impl_user_async_handles_count(node_impl) == 0) { loader_impl_handle_safe_cast destroy_prepare_cast = { NULL }; loader_impl_handle_safe_cast destroy_check_cast = { NULL }; @@ -4297,6 +4402,15 @@ static void node_loader_impl_destroy_check_cb(uv_check_t *handle) node_loader_impl_destroy_cb(node_impl); } +void node_loader_impl_destroy_hook(loader_impl_node node_impl) +{ + node_impl->extra_active_handles.store(2); + uv_prepare_init(node_impl->thread_loop, &node_impl->destroy_prepare); + uv_check_init(node_impl->thread_loop, &node_impl->destroy_check); + uv_prepare_start(&node_impl->destroy_prepare, &node_loader_impl_destroy_prepare_cb); + uv_check_start(&node_impl->destroy_check, &node_loader_impl_destroy_check_cb); +} + void node_loader_impl_destroy_safe(napi_env env, loader_impl_async_destroy_safe_type *destroy_safe) { napi_status status; @@ -4310,18 +4424,14 @@ void node_loader_impl_destroy_safe(napi_env env, loader_impl_async_destroy_safe_ node_loader_impl_exception(env, status); /* Check if there are async handles, destroy if the queue is empty, otherwise request the destroy */ - if (node_loader_impl_user_async_handles_count(node_impl) <= 0 || node_impl->event_loop_empty.load() == true) + if (node_loader_impl_user_async_handles_count(node_impl) == 0 || node_impl->event_loop_empty.load() == true) { node_loader_impl_destroy_safe_impl(node_impl, env); destroy_safe->has_finished = true; } else { - node_impl->extra_active_handles.store(2); - uv_prepare_init(node_impl->thread_loop, &node_impl->destroy_prepare); - uv_check_init(node_impl->thread_loop, &node_impl->destroy_check); - uv_prepare_start(&node_impl->destroy_prepare, &node_loader_impl_destroy_prepare_cb); - uv_check_start(&node_impl->destroy_check, &node_loader_impl_destroy_check_cb); + node_loader_impl_destroy_hook(node_impl); } /* Close scope */ @@ -4346,7 +4456,7 @@ static inline int uv__queue_empty(const struct node_loader_impl_uv__queue *q) #if (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) void node_loader_impl_walk_async_handles_count(uv_handle_t *handle, void *arg) { - int64_t *async_count = static_cast(arg); + uint64_t *async_count = static_cast(arg); if (uv_is_active(handle) && !uv_is_closing(handle)) { @@ -4362,11 +4472,11 @@ void node_loader_impl_walk_async_handles_count(uv_handle_t *handle, void *arg) } #endif -int64_t node_loader_impl_async_closing_handles_count(loader_impl_node node_impl) +uint64_t node_loader_impl_async_closing_handles_count(loader_impl_node node_impl) { #if defined(WIN32) || defined(_WIN32) - return (int64_t)(node_impl->thread_loop->pending_reqs_tail != NULL) + - (int64_t)(node_impl->thread_loop->endgame_handles != NULL); + return (uint64_t)(node_impl->thread_loop->pending_reqs_tail != NULL) + + (uint64_t)(node_impl->thread_loop->endgame_handles != NULL); #else union { @@ -4376,49 +4486,66 @@ int64_t node_loader_impl_async_closing_handles_count(loader_impl_node node_impl) uv__queue_cast.data = (void *)&node_impl->thread_loop->pending_queue; - return (int64_t)(!uv__queue_empty(uv__queue_cast.ptr)) + - (int64_t)(node_impl->thread_loop->closing_handles != NULL); + return (uint64_t)(!uv__queue_empty(uv__queue_cast.ptr)) + + (uint64_t)(node_impl->thread_loop->closing_handles != NULL); #endif } -int64_t node_loader_impl_async_handles_count(loader_impl_node node_impl) +uint64_t node_loader_impl_async_handles_count(loader_impl_node node_impl) { #if (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) - int64_t active_handles = 0; + uint64_t active_handles = 0; uv_walk(node_impl->thread_loop, node_loader_impl_walk_async_handles_count, (void *)&active_handles); return active_handles + - (int64_t)(node_impl->thread_loop->active_reqs.count > 0) + + (uint64_t)(node_impl->thread_loop->active_reqs.count > 0) + node_loader_impl_async_closing_handles_count(node_impl); #else - int64_t active_handles = (int64_t)node_impl->thread_loop->active_handles + - (int64_t)(node_impl->thread_loop->active_reqs.count > 0) + - node_loader_impl_async_closing_handles_count(node_impl); + uint64_t active_handles = (uint64_t)node_impl->thread_loop->active_handles + + (uint64_t)(node_impl->thread_loop->active_reqs.count > 0) + + node_loader_impl_async_closing_handles_count(node_impl); return active_handles; #endif } -int64_t node_loader_impl_user_async_handles_count(loader_impl_node node_impl) +uint64_t node_loader_impl_user_async_handles_count(loader_impl_node node_impl) { - int64_t active_handles = node_loader_impl_async_handles_count(node_impl); - int64_t extra_active_handles = node_impl->extra_active_handles.load(); + uint64_t active_handles = node_loader_impl_async_handles_count(node_impl); + uint64_t extra_active_handles = node_impl->extra_active_handles.load(); + uint64_t base_active_handles = node_impl->base_active_handles; /* TODO: Uncomment for debugging handles */ /* #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) - int64_t closing = node_loader_impl_async_closing_handles_count(node_impl); + uint64_t closing = node_loader_impl_async_closing_handles_count(node_impl); printf("[active_handles] - [base_active_handles] - [extra_active_handles] + [active_reqs] + [closing]\n"); - printf(" %" PRId64 " - %" PRId64 " - %" PRId64 " + %" PRId64 " [> 0] + %" PRId64 "\n", - (int64_t)node_impl->thread_loop->active_handles, - node_impl->base_active_handles, + printf(" %" PRIu64 " - %" PRIu64 " - %" PRIu64 " + %" PRIu64 " [> 0] + %" PRIu64 "\n", + (uint64_t)node_impl->thread_loop->active_handles, + base_active_handles, extra_active_handles, - (int64_t)node_impl->thread_loop->active_reqs.count, + (uint64_t)node_impl->thread_loop->active_reqs.count, closing); #endif */ - return active_handles - node_impl->base_active_handles - extra_active_handles; + /* Check for overflow */ + uint64_t total_base_handles = base_active_handles + extra_active_handles; + + if (total_base_handles < base_active_handles) + { + /* Overflow occurred */ + return UINT64_MAX; + } + + /* Check for underflow */ + if (active_handles < total_base_handles) + { + /* Underflow occurred */ + return 0; + } + + return active_handles - total_base_handles; } void node_loader_impl_print_handles(loader_impl_node node_impl) @@ -4427,8 +4554,8 @@ void node_loader_impl_print_handles(loader_impl_node node_impl) /* TODO: Uncomment for debugging handles */ /* - printf("Number of active handles: %" PRId64 "\n", node_loader_impl_async_handles_count(node_impl)); - printf("Number of user active handles: %" PRId64 "\n", node_loader_impl_user_async_handles_count(node_impl)); + printf("Number of active handles: %" PRIu64 "\n", node_loader_impl_async_handles_count(node_impl)); + printf("Number of user active handles: %" PRIu64 "\n", node_loader_impl_user_async_handles_count(node_impl)); uv_print_active_handles(node_impl->thread_loop, stdout); fflush(stdout); */ @@ -4468,6 +4595,7 @@ void node_loader_impl_destroy_safe_impl(loader_impl_node node_impl, napi_env env node_loader_impl_exception(env, status); /* Clear thread safe functions except by destroy one */ + if (loader_impl_get_option_host(node_impl->impl) == 0) { node_impl->threadsafe_initialize.abort(env); node_impl->threadsafe_execution_path.abort(env); @@ -4520,9 +4648,12 @@ void node_loader_impl_try_destroy(loader_impl_node node_impl) loader_impl_threadsafe_invoke_type invoke(node_impl->threadsafe_destroy, destroy_safe); } - if (destroy_safe.has_finished) + if (loader_impl_get_option_host(node_impl->impl) == 0) { - node_impl->threadsafe_destroy.abort(node_impl->env); + if (destroy_safe.has_finished) + { + node_impl->threadsafe_destroy.abort(node_impl->env); + } } } @@ -4535,11 +4666,14 @@ int node_loader_impl_destroy(loader_impl impl) return 1; } - /* Call destroy function with thread safe */ - node_loader_impl_try_destroy(node_impl); + if (loader_impl_get_option_host(impl) == 0) + { + /* Call destroy function with thread safe */ + node_loader_impl_try_destroy(node_impl); - /* Wait for node thread to finish */ - uv_thread_join(&node_impl->thread); + /* Wait for node thread to finish */ + uv_thread_join(&node_impl->thread); + } /* Clear condition syncronization object */ uv_cond_destroy(&node_impl->cond); @@ -4556,6 +4690,20 @@ int node_loader_impl_destroy(loader_impl impl) uv_thread_join(&node_impl->thread_log_id); #endif + /* On Windows, destroy the node extension hooking mechanism */ +#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1200) + { + if (node_module_handle_a_handle != NULL) + { + detour d = detour_create(metacall_detour()); + + detour_unload(d, node_module_handle_a_handle); + + node_module_handle_a_handle = NULL; + } + } +#endif + /* Print NodeJS execution result */ log_write("metacall", LOG_LEVEL_DEBUG, "NodeJS execution return status %d", node_impl->result); diff --git a/source/loaders/node_loader/source/node_loader_port.cpp b/source/loaders/node_loader/source/node_loader_port.cpp index ed681f1e91..82eaafbff9 100644 --- a/source/loaders/node_loader/source/node_loader_port.cpp +++ b/source/loaders/node_loader/source/node_loader_port.cpp @@ -2,7 +2,7 @@ * MetaCall NodeJS Port by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -281,6 +281,94 @@ napi_value node_loader_port_metacall_await(napi_env env, napi_callback_info info return promise; } +/** +* @brief +* Define an execution path into a runtime +* +* @param[in] env +* N-API reference to the enviroment +* +* @param[in] info +* Reference to the call information +* +* @return +* TODO: Not implemented yet +*/ +napi_value node_loader_port_metacall_execution_path(napi_env env, napi_callback_info info) +{ + const size_t args_size = 2; + size_t argc = args_size, tag_length, path_length; + napi_value argv[args_size]; + + /* Get arguments */ + napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + node_loader_impl_exception(env, status); + + /* Get tag length */ + status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tag_length); + + node_loader_impl_exception(env, status); + + /* Allocate tag */ + char *tag = new char[tag_length + 1]; + + if (tag == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not define an execution path, tag allocation failed"); + return nullptr; + } + + /* Get tag */ + status = napi_get_value_string_utf8(env, argv[0], tag, tag_length + 1, &tag_length); + + node_loader_impl_exception(env, status); + + /* Get path length */ + status = napi_get_value_string_utf8(env, argv[1], nullptr, 0, &path_length); + + node_loader_impl_exception(env, status); + + size_t path_size = path_length + 1; + + /* Allocate path */ + char *path = new char[path_size]; + + if (path == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not define an execution path, path allocation failed"); + delete[] tag; + return nullptr; + } + + /* Get path */ + status = napi_get_value_string_utf8(env, argv[1], path, path_size, &path_length); + + node_loader_impl_exception(env, status); + + /* Obtain NodeJS loader implementation */ + loader_impl impl = loader_get_impl(node_loader_tag); + loader_impl_node node_impl = (loader_impl_node)loader_impl_get(impl); + + /* Store current reference of the environment */ + node_loader_impl_env(node_impl, env); + + /* Define execution path */ + if (metacall_execution_path(tag, path) != 0) + { + napi_throw_error(env, nullptr, "MetaCall could not define an execution path"); + } + + /* Release current reference of the environment */ + // node_loader_impl_env(node_impl, nullptr); + + delete[] tag; + delete[] path; + + /* TODO: Return value and logs */ + return nullptr; +} + napi_value node_loader_port_metacall_load_from_file(napi_env env, napi_callback_info info) { /* TODO: Detect if input argument types are valid */ @@ -628,6 +716,176 @@ napi_value node_loader_port_metacall_load_from_memory_export(napi_env env, napi_ return v_exports; } +/** +* @brief +* Load a package by tag +* +* @param[in] env +* N-API reference to the enviroment +* +* @param[in] info +* Reference to the call information +* +* @return +* TODO: Not implemented yet +*/ +napi_value node_loader_port_metacall_load_from_package(napi_env env, napi_callback_info info) +{ + const size_t args_size = 2; + size_t argc = args_size, tag_length, package_length; + napi_value argv[args_size]; + + /* Get arguments */ + napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + node_loader_impl_exception(env, status); + + /* Get tag length */ + status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tag_length); + + node_loader_impl_exception(env, status); + + /* Allocate tag */ + char *tag = new char[tag_length + 1]; + + if (tag == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not load from package, tag allocation failed"); + return nullptr; + } + + /* Get tag */ + status = napi_get_value_string_utf8(env, argv[0], tag, tag_length + 1, &tag_length); + + node_loader_impl_exception(env, status); + + /* Get package length */ + status = napi_get_value_string_utf8(env, argv[1], nullptr, 0, &package_length); + + node_loader_impl_exception(env, status); + + size_t package_size = package_length + 1; + + /* Allocate package */ + char *package = new char[package_size]; + + if (package == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not load from package, package allocation failed"); + delete[] tag; + return nullptr; + } + + /* Get package */ + status = napi_get_value_string_utf8(env, argv[1], package, package_size, &package_length); + + node_loader_impl_exception(env, status); + + /* Obtain NodeJS loader implementation */ + loader_impl impl = loader_get_impl(node_loader_tag); + loader_impl_node node_impl = (loader_impl_node)loader_impl_get(impl); + + /* Store current reference of the environment */ + node_loader_impl_env(node_impl, env); + + /* Load the package */ + if (metacall_load_from_package(tag, package, NULL) != 0) + { + napi_throw_error(env, nullptr, "MetaCall could not load a package"); + } + + /* Release current reference of the environment */ + // node_loader_impl_env(node_impl, nullptr); + + delete[] tag; + delete[] package; + + /* TODO: Return value and logs */ + return nullptr; +} + +napi_value node_loader_port_metacall_load_from_package_export(napi_env env, napi_callback_info info) +{ + const size_t args_size = 2; + size_t argc = args_size, tag_length, package_length; + napi_value argv[args_size]; + + /* Get arguments */ + napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + node_loader_impl_exception(env, status); + + /* Get tag length */ + status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tag_length); + + node_loader_impl_exception(env, status); + + /* Allocate tag */ + char *tag = new char[tag_length + 1]; + + if (tag == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not load from memory, tag allocation failed"); + return nullptr; + } + + /* Get tag */ + status = napi_get_value_string_utf8(env, argv[0], tag, tag_length + 1, &tag_length); + + node_loader_impl_exception(env, status); + + /* Get package length */ + status = napi_get_value_string_utf8(env, argv[1], nullptr, 0, &package_length); + + node_loader_impl_exception(env, status); + + size_t package_size = package_length + 1; + + /* Allocate package */ + char *package = new char[package_size]; + + if (package == nullptr) + { + napi_throw_error(env, nullptr, "MetaCall could not load from package, package allocation failed"); + delete[] tag; + return nullptr; + } + + /* Get package */ + status = napi_get_value_string_utf8(env, argv[1], package, package_size, &package_length); + + node_loader_impl_exception(env, status); + + /* Obtain NodeJS loader implementation */ + loader_impl impl = loader_get_impl(node_loader_tag); + loader_impl_node node_impl = (loader_impl_node)loader_impl_get(impl); + + /* Store current reference of the environment */ + node_loader_impl_env(node_impl, env); + + void *handle = NULL; + + /* Load package from package */ + if (metacall_load_from_package(tag, package, &handle) != 0) + { + napi_throw_error(env, nullptr, "MetaCall could not load from package"); + } + + /* Release current reference of the environment */ + // node_loader_impl_env(node_impl, nullptr); + + delete[] tag; + delete[] package; + + void *exports = metacall_handle_export(handle); + + napi_value v_exports = node_loader_impl_value_to_napi(node_impl, env, exports); + + node_loader_impl_finalizer(env, v_exports, exports); + + return v_exports; +} + /** * @brief * Loads a script from configuration path @@ -799,6 +1057,19 @@ napi_value node_loader_port_metacall_logs(napi_env env, napi_callback_info) return nullptr; } +napi_value node_loader_port_register_bootstrap_startup(napi_env env, napi_callback_info) +{ + /* Obtain NodeJS loader implementation */ + loader_impl impl = loader_get_impl(node_loader_tag); + loader_impl_node node_impl = static_cast(loader_impl_get(impl)); + + /* Define environment, required to initialize the runtime properly */ + node_loader_impl_env(node_impl, env); + + /* Return all the values required for the bootstrap startup */ + return node_loader_impl_register_bootstrap_startup(node_impl, env); +} + /* TODO: Review documentation */ // This functions sets the necessary js functions that could be called in NodeJs void node_loader_port_exports(napi_env env, napi_value exports) @@ -816,14 +1087,18 @@ void node_loader_port_exports(napi_env env, napi_value exports) x(metacall); \ x(metacallfms); \ x(metacall_await); \ + x(metacall_execution_path); \ x(metacall_load_from_file); \ x(metacall_load_from_file_export); \ x(metacall_load_from_memory); \ x(metacall_load_from_memory_export); \ + x(metacall_load_from_package); \ + x(metacall_load_from_package_export); \ x(metacall_load_from_configuration); \ x(metacall_load_from_configuration_export); \ x(metacall_inspect); \ - x(metacall_logs); + x(metacall_logs); \ + x(register_bootstrap_startup); /* Declare all the functions */ NODE_LOADER_PORT_DECL_X_MACRO(NODE_LOADER_PORT_DECL_FUNC) @@ -836,18 +1111,13 @@ void node_loader_port_exports(napi_env env, napi_value exports) /* This function is called by NodeJs when the module is required */ napi_value node_loader_port_initialize(napi_env env, napi_value exports) { -/* Note: This should not be necessary because we do not allow to use ports outside MetaCall */ -#if 0 - if (metacall_initialize() != 0) - { - /* TODO: Show error message (when error handling is properly implemented in the core lib) */ - napi_throw_error(env, nullptr, "MetaCall failed to initialize"); + node_loader_port_exports(env, exports); - return nullptr; + /* Unregister NAPI Hook */ + if (metacall_link_unregister(node_loader_tag, "node", "napi_register_module_v1") != 0) + { + // TODO: Handle error } -#endif - - node_loader_port_exports(env, exports); return exports; } diff --git a/source/loaders/node_loader/source/node_loader_trampoline.cpp b/source/loaders/node_loader/source/node_loader_trampoline.cpp index 184fbbcda3..5d5aebbc89 100644 --- a/source/loaders/node_loader/source/node_loader_trampoline.cpp +++ b/source/loaders/node_loader/source/node_loader_trampoline.cpp @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading nodejs code at run-time into a process. * @@ -9,7 +9,8 @@ #include #include -#include /* TODO: Improve this trick */ +#include +#include /* TODO: Improve this trick */ #define NODE_LOADER_TRAMPOLINE_DECLARE_NAPI_METHOD(name, func) \ { \ @@ -45,7 +46,7 @@ union loader_impl_trampoline_cast */ static void node_loader_trampoline_parse_pointer(napi_env env, napi_value v, void **ptr) { - const size_t ptr_str_size = (sizeof(void *) * 2) + 1; + const size_t ptr_str_size = (sizeof(uintptr_t) * 2) + 1; size_t ptr_str_size_copied = 0; char ptr_str[ptr_str_size]; napi_status status = napi_get_value_string_utf8(env, v, ptr_str, ptr_str_size, &ptr_str_size_copied); @@ -53,7 +54,9 @@ static void node_loader_trampoline_parse_pointer(napi_env env, napi_value v, voi node_loader_impl_exception(env, status); /* Convert the string to pointer type */ - sscanf(ptr_str, "%p", ptr); + uintptr_t uint_ptr; + sscanf(ptr_str, "%" SCNxPTR, &uint_ptr); + *ptr = (void *)uint_ptr; } napi_value node_loader_trampoline_register(napi_env env, napi_callback_info info) @@ -244,7 +247,6 @@ napi_value node_loader_trampoline_reject(napi_env env, napi_callback_info info) napi_value node_loader_trampoline_destroy(napi_env env, napi_callback_info info) { napi_status status; - const size_t args_size = 1; size_t argc = args_size; napi_value recv; @@ -395,12 +397,17 @@ napi_value node_loader_trampoline_active_handles(napi_env env, napi_callback_inf return nullptr; } - int64_t active_handles = node_loader_impl_user_async_handles_count(node_impl_cast.data); + uint64_t active_handles = node_loader_impl_user_async_handles_count(node_impl_cast.data); /* Create the integer return value */ napi_value result; - status = napi_create_int64(env, active_handles, &result); + if (active_handles > (uint64_t)INT64_MAX) + { + active_handles = (uint64_t)INT64_MAX; + } + + status = napi_create_int64(env, (int64_t)active_handles, &result); node_loader_impl_exception(env, status); @@ -427,3 +434,31 @@ napi_value node_loader_trampoline_initialize(napi_env env, napi_value exports) return exports; } + +#define NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD(name, func) \ + do \ + { \ + napi_value func_value; \ + status = napi_create_function(env, name, NAPI_AUTO_LENGTH, func, nullptr, &func_value); \ + node_loader_impl_exception(env, status); \ + napi_set_named_property(env, obj, name, func_value); \ + node_loader_impl_exception(env, status); \ + } while (0) + +napi_value node_loader_trampoline_initialize_object(napi_env env) +{ + napi_value obj; + napi_status status; + + status = napi_create_object(env, &obj); + node_loader_impl_exception(env, status); + + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("register", node_loader_trampoline_register); + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("resolve", node_loader_trampoline_resolve); + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("reject", node_loader_trampoline_reject); + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("destroy", node_loader_trampoline_destroy); + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("print", node_loader_trampoline_print); + NODE_LOADER_TRAMPOLINE_DECLARE_OBJ_METHOD("active_handles", node_loader_trampoline_active_handles); + + return obj; +} diff --git a/source/loaders/py_loader/CMakeLists.txt b/source/loaders/py_loader/CMakeLists.txt index eed3658bc7..06d73b1127 100644 --- a/source/loaders/py_loader/CMakeLists.txt +++ b/source/loaders/py_loader/CMakeLists.txt @@ -9,15 +9,45 @@ endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(Python3_FIND_ABI "ON" "ANY" "ANY") - find_package(Python3 COMPONENTS Development) + find_package(Python3 COMPONENTS Interpreter Development) # Fallback to release if not found if(NOT Python3_Development_FOUND) set(Python3_FIND_ABI) - find_package(Python3 COMPONENTS Development REQUIRED) + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) endif() else() - find_package(Python3 COMPONENTS Development REQUIRED) + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) +endif() + +# Select the proper library +if(NOT Python3_LIBRARY AND Python3_LIBRARIES) + # Go through the list and handle keyword-separated structure + set(index 0) + list(LENGTH Python3_LIBRARIES lib_len) + while(index LESS lib_len) + list(GET Python3_LIBRARIES ${index} item) + + # Check if it's a keyword (debug/optimized) + if(item STREQUAL "debug" OR item STREQUAL "optimized" OR item STREQUAL "general") + set(keyword ${item}) + math(EXPR next "${index} + 1") + list(GET Python3_LIBRARIES ${next} lib_path) + + # Match the right keyword + if((CMAKE_BUILD_TYPE STREQUAL "Debug" AND keyword STREQUAL "debug") OR + (NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND keyword STREQUAL "optimized") OR + (keyword STREQUAL "general")) # general applies to all configs + set(Python3_LIBRARY ${lib_path}) + endif() + + math(EXPR index "${index} + 2") # Skip keyword and path + else() + # Plain list without keywords (single-config or fallback) + set(Python3_LIBRARY ${item}) + math(EXPR index "${index} + 1") + endif() + endwhile() endif() # Copy Python DLL into project output directory @@ -25,28 +55,27 @@ endif() # TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da 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 ${LIB_NAME} - PATHS ${Python3_ROOT_DIR} - NO_DEFAULT_PATH - ) - if(Python3_LIBRARY_NAME) - break() - endif() - endif() - endforeach() +if(PROJECT_OS_FAMILY STREQUAL win32 AND Python3_LIBRARY) + # Get the library path with dll suffix + string(REGEX REPLACE "[.]lib$" ".dll" LIB_PATH "${Python3_LIBRARY}") + # Get the library name + get_filename_component(LIB_NAME "${LIB_PATH}" NAME) + # Get the python root folder + if(NOT Python3_ROOT_DIR) + get_filename_component(Python3_ROOT_DIR "${Python3_EXECUTABLE}" DIRECTORY) + endif() + # Find the library in the Python3 root path + find_file(Python3_LIBRARY_NAME_PATH "${LIB_NAME}" + PATHS "${Python3_ROOT_DIR}" + NO_DEFAULT_PATH + ) + # Copy the DLL to the output directory + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_OUTPUT_DIR}") + file(COPY "${Python3_LIBRARY_NAME_PATH}" DESTINATION "${PROJECT_OUTPUT_DIR}") endif() -if(Python3_LIBRARY_NAME) - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_OUTPUT_DIR}) - file(COPY "${Python3_LIBRARY_NAME}" DESTINATION ${PROJECT_OUTPUT_DIR}) +if(NOT Python3_LIBRARY_NAME_PATH) + set(Python3_LIBRARY_NAME_PATH "${Python3_LIBRARY}") endif() # @@ -89,6 +118,7 @@ set(headers ${include_path}/py_loader_port.h ${include_path}/py_loader_threading.h ${include_path}/py_loader_dict.h + ${include_path}/py_loader_symbol_fallback.h ) set(sources @@ -97,6 +127,7 @@ set(sources ${source_path}/py_loader_port.c ${source_path}/py_loader_threading.cpp ${source_path}/py_loader_dict.c + ${source_path}/py_loader_symbol_fallback.c ) # Group source files @@ -169,7 +200,10 @@ target_include_directories(${target} target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library - ${Python3_LIBRARIES} # Python libraries + + # Delay load for MSVC + $<$:${Python3_LIBRARY}> # Python library + $<$:delayimp> PUBLIC ${DEFAULT_LIBRARIES} @@ -183,7 +217,6 @@ target_link_libraries(${target} target_compile_definitions(${target} PRIVATE - PY_LOADER_PORT_NAME=$<$>:lib>py_loader$<$:d> PUBLIC $<$>:${target_upper}_STATIC_DEFINE> @@ -209,8 +242,12 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +get_filename_component(Python3_LIBRARY_NAME "${Python3_LIBRARY_NAME_PATH}" NAME) + +target_link_options(${target} PRIVATE + $<$,$>:-Wl,-undefined,dynamic_lookup> + $<$:/DELAYLOAD:${Python3_LIBRARY_NAME}> PUBLIC ${DEFAULT_LINKER_OPTIONS} @@ -233,10 +270,30 @@ install(TARGETS ${target} # Runtime (pack Python DLL in windows) # TODO: https://cmake.org/cmake/help/latest/command/file.html#get-runtime-dependencies # TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da -if(Python3_LIBRARY_NAME) +set(Python3_LIBRARY_DEVELOPMENT "${Python3_LIBRARY_NAME_PATH}") + +if(Python3_LIBRARY_NAME_PATH AND PROJECT_OS_FAMILY STREQUAL win32) install(FILES - "${Python3_LIBRARY_NAME}" + "${Python3_LIBRARY_NAME_PATH}" DESTINATION ${INSTALL_LIB} COMPONENT runtime ) + + set(Python3_LIBRARY_INSTALL "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/${Python3_LIBRARY_NAME}") +else() + set(Python3_LIBRARY_INSTALL "${Python3_LIBRARY_NAME_PATH}") endif() + +# +# Configuration +# + +# Development +loader_configuration_begin(py_loader) +loader_configuration_deps(python "${Python3_LIBRARY_DEVELOPMENT}") +loader_configuartion_end_development() + +# Install +loader_configuration_begin(py_loader) +loader_configuration_deps(python "${Python3_LIBRARY_INSTALL}") +loader_configuartion_end_install() diff --git a/source/loaders/py_loader/include/py_loader/py_loader.h b/source/loaders/py_loader/include/py_loader/py_loader.h index 0e655cdb81..54b1515860 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader.h +++ b/source/loaders/py_loader/include/py_loader/py_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif PY_LOADER_API loader_impl_interface py_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(py_loader_impl_interface_singleton); - PY_LOADER_API const char *py_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(py_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/py_loader/include/py_loader/py_loader_dict.h b/source/loaders/py_loader/include/py_loader/py_loader_dict.h index 6c874786ee..be17ab153b 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader_dict.h +++ b/source/loaders/py_loader/include/py_loader/py_loader_dict.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. 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 efa286a6ea..bc1a081ede 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 @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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/include/py_loader/py_loader_port.h b/source/loaders/py_loader/include/py_loader/py_loader_port.h index 8e4e18eb27..617ba0d5d2 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader_port.h +++ b/source/loaders/py_loader/include/py_loader/py_loader_port.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +21,13 @@ #ifndef PY_LOADER_PORT_H #define PY_LOADER_PORT_H 1 -#include +#include #ifdef __cplusplus extern "C" { #endif -#define PY_LOADER_PORT_NAME_FUNC_IMPL_EXPAND(x) PyInit_##x -#define PY_LOADER_PORT_NAME_FUNC_IMPL(x) PY_LOADER_PORT_NAME_FUNC_IMPL_EXPAND(x) -#define PY_LOADER_PORT_NAME_FUNC PY_LOADER_PORT_NAME_FUNC_IMPL(PY_LOADER_PORT_NAME) - -PyMODINIT_FUNC PY_LOADER_PORT_NAME_FUNC(void); +PY_LOADER_NO_EXPORT int py_port_initialize(void); #ifdef __cplusplus } diff --git a/source/loaders/py_loader/include/py_loader/py_loader_symbol_fallback.h b/source/loaders/py_loader/include/py_loader/py_loader_symbol_fallback.h new file mode 100644 index 0000000000..cc6d005757 --- /dev/null +++ b/source/loaders/py_loader/include/py_loader/py_loader_symbol_fallback.h @@ -0,0 +1,80 @@ +/* + * Loader Library by Parra Studios + * A plugin for loading python code at run-time into a process. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 PY_LOADER_SYMBOL_FALLBACK_H +#define PY_LOADER_SYMBOL_FALLBACK_H 1 + +#include + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +PY_LOADER_NO_EXPORT int py_loader_symbol_fallback_initialize(dynlink py_library); + +#if defined(_WIN32) && defined(_MSC_VER) + #undef PyCFunction_GET_FUNCTION + #define PyCFunction_GET_FUNCTION(func) \ + (((PyCFunctionObject *)func)->m_ml->ml_meth) + + #undef PyCFunction_GET_SELF + #define PyCFunction_GET_SELF(func) \ + (((PyCFunctionObject *)func)->m_ml->ml_flags & METH_STATIC ? \ + NULL : \ + ((PyCFunctionObject *)func)->m_self) + + #undef PyBool_Check +PY_LOADER_NO_EXPORT int PyBool_Check(const PyObject *ob); + #undef PyFloat_Check +PY_LOADER_NO_EXPORT int PyFloat_Check(const PyObject *ob); + #undef PyCapsule_CheckExact +PY_LOADER_NO_EXPORT int PyCapsule_CheckExact(const PyObject *ob); + #undef PyFunction_Check +PY_LOADER_NO_EXPORT int PyFunction_Check(const PyObject *ob); + #undef PyCFunction_Check +PY_LOADER_NO_EXPORT int PyCFunction_Check(const PyObject *ob); + #undef PyModule_Check +PY_LOADER_NO_EXPORT int PyModule_Check(const PyObject *ob); +#endif + +PY_LOADER_NO_EXPORT PyTypeObject *PyCFunctionTypePtr(void); +PY_LOADER_NO_EXPORT PyTypeObject *PyStaticMethodTypePtr(void); +PY_LOADER_NO_EXPORT PyTypeObject *PyDictProxyTypePtr(void); +PY_LOADER_NO_EXPORT PyTypeObject *PyDictTypePtr(void); +PY_LOADER_NO_EXPORT PyTypeObject *PyTypeTypePtr(void); +PY_LOADER_NO_EXPORT PyObject *Py_NonePtr(void); +PY_LOADER_NO_EXPORT PyObject *PyExc_ExceptionPtr(void); +PY_LOADER_NO_EXPORT PyObject *PyExc_FileNotFoundErrorPtr(void); +PY_LOADER_NO_EXPORT PyObject *PyExc_TypeErrorPtr(void); +PY_LOADER_NO_EXPORT PyObject *PyExc_ValueErrorPtr(void); +PY_LOADER_NO_EXPORT PyObject *PyExc_RuntimeErrorPtr(void); +PY_LOADER_NO_EXPORT PyObject *Py_ReturnNone(void); +PY_LOADER_NO_EXPORT PyObject *Py_ReturnFalse(void); +PY_LOADER_NO_EXPORT PyObject *Py_ReturnTrue(void); + +#ifdef __cplusplus +} +#endif + +#endif /* PY_LOADER_SYMBOL_FALLBACK_H */ diff --git a/source/loaders/py_loader/include/py_loader/py_loader_threading.h b/source/loaders/py_loader/include/py_loader/py_loader_threading.h index 6dbc9dc4d0..d55a804b7d 100644 --- a/source/loaders/py_loader/include/py_loader/py_loader_threading.h +++ b/source/loaders/py_loader/include/py_loader/py_loader_threading.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,13 @@ #include +#include + #ifdef __cplusplus extern "C" { #endif -PY_LOADER_NO_EXPORT void py_loader_thread_initialize(void); +PY_LOADER_NO_EXPORT int py_loader_thread_initialize(const int host); PY_LOADER_NO_EXPORT int py_loader_thread_is_main(void); @@ -35,6 +37,10 @@ PY_LOADER_NO_EXPORT void py_loader_thread_acquire(void); PY_LOADER_NO_EXPORT void py_loader_thread_release(void); +PY_LOADER_NO_EXPORT void py_loader_thread_delayed_destroy(PyObject *obj); + +PY_LOADER_NO_EXPORT void py_loader_thread_destroy(void); + #ifdef __cplusplus } #endif diff --git a/source/loaders/py_loader/source/py_loader.c b/source/loaders/py_loader/source/py_loader.c index f3bf421fb2..ecdc14e009 100644 --- a/source/loaders/py_loader/source/py_loader.c +++ b/source/loaders/py_loader/source/py_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *py_loader_print_info(void) { static const char py_loader_info[] = "Python Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef PY_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/py_loader/source/py_loader_dict.c b/source/loaders/py_loader/source/py_loader_dict.c index 022ff7c9a8..abfed7a0ab 100644 --- a/source/loaders/py_loader/source/py_loader_dict.c +++ b/source/loaders/py_loader/source/py_loader_dict.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,15 +23,38 @@ #include -#include - #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13 + /* Disable warnings from Python */ + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wredundant-decls" + #pragma clang diagnostic ignored "-Wstrict-aliasing" + #pragma clang diagnostic ignored "-Wunused-parameter" + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wredundant-decls" + #pragma GCC diagnostic ignored "-Wstrict-aliasing" + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif + #ifndef Py_BUILD_CORE #define Py_BUILD_CORE #endif #include + #undef Py_BUILD_CORE + + /* Disable warnings from Python */ + #if defined(__clang__) + #pragma clang diagnostic pop + #elif defined(__GNUC__) + #pragma GCC diagnostic pop + #endif #endif +#include + struct py_loader_impl_dict_obj { PyDictObject dict; @@ -124,7 +147,7 @@ PyObject *py_loader_impl_dict_sizeof(struct py_loader_impl_dict_obj *self, void int py_loader_impl_dict_init(struct py_loader_impl_dict_obj *self, PyObject *args, PyObject *kwds) { - if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + if (PyDictTypePtr()->tp_init((PyObject *)self, args, kwds) < 0) return -1; self->v = NULL; return 0; @@ -133,15 +156,15 @@ int py_loader_impl_dict_init(struct py_loader_impl_dict_obj *self, PyObject *arg void py_loader_impl_dict_dealloc(struct py_loader_impl_dict_obj *self) { metacall_value_destroy(self->v); - Py_DECREF(self->parent); /* TODO: Review if this is correct or this line is unnecessary */ + Py_DecRef(self->parent); /* TODO: Review if this is correct or this line is unnecessary */ - PyDict_Type.tp_dealloc((PyObject *)self); + PyDictTypePtr()->tp_dealloc((PyObject *)self); } int py_loader_impl_dict_type_init(void) { /* py_loader_impl_dict_type is derived from PyDict_Type */ - py_loader_impl_dict_type.tp_base = &PyDict_Type; + py_loader_impl_dict_type.tp_base = PyDictTypePtr(); return PyType_Ready(&py_loader_impl_dict_type); } @@ -154,9 +177,9 @@ PyObject *py_loader_impl_finalizer_wrap_map(PyObject *obj, void *v) union py_loader_impl_dict_cast dict_cast = { &py_loader_impl_dict_type }; PyTuple_SetItem(args, 0, obj); - Py_INCREF(obj); + Py_IncRef(obj); PyObject *wrapper = PyObject_CallObject(dict_cast.object, args); - Py_DECREF(args); + Py_DecRef(args); py_loader_thread_release(); diff --git a/source/loaders/py_loader/source/py_loader_impl.c b/source/loaders/py_loader/source/py_loader_impl.c index 66be1c0b94..77fc87016a 100644 --- a/source/loaders/py_loader/source/py_loader_impl.c +++ b/source/loaders/py_loader/source/py_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,6 @@ #include #include -#include - #define PY_LOADER_IMPL_FUNCTION_TYPE_INVOKE_FUNC "__py_loader_impl_function_type_invoke__" #define PY_LOADER_IMPL_FINALIZER_FUNC "__py_loader_impl_finalizer__" @@ -55,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 0 + typedef struct loader_impl_py_function_type { PyObject *func; @@ -122,6 +127,7 @@ struct loader_impl_py_type PyObject *thread_background_start; PyObject *thread_background_send; PyObject *thread_background_stop; + PyObject *thread_background_register_atexit; PyObject *py_task_callback_handler; /* End asyncio required modules */ @@ -160,8 +166,10 @@ 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 static void py_loader_impl_sys_path_print(PyObject *sys_path_list); #endif @@ -194,7 +202,7 @@ static void py_loader_impl_value_invoke_state_finalize(value v, void *data); static void py_loader_impl_value_ptr_finalize(value v, void *data); -static int py_loader_impl_finalize(loader_impl_py py_impl); +static int py_loader_impl_finalize(loader_impl_py py_impl, const int host); static PyObject *py_loader_impl_load_from_memory_compile(loader_impl_py py_impl, const loader_name name, const char *buffer); @@ -224,19 +232,21 @@ static void (*py_loader_impl_pycfunction_dealloc)(PyObject *) = NULL; /* Implements PyCapsules with null value internally */ static const char py_loader_capsule_null_id[] = "__metacall_capsule_null__"; -PyObject *py_loader_impl_finalizer_object_impl(PyObject *self, PyObject *Py_UNUSED(args)) +PyObject *py_loader_impl_finalizer_object_impl(PyObject *self, PyObject *args) { value v = PyCapsule_GetPointer(self, NULL); + (void)args; + if (v == NULL) { log_write("metacall", LOG_LEVEL_ERROR, "Fatal error destroying a value, the metacall value attached to the python value is null"); - Py_RETURN_NONE; + return Py_ReturnNone(); } value_type_destroy(v); - Py_RETURN_NONE; + return Py_ReturnNone(); } int py_loader_impl_finalizer_object(loader_impl impl, PyObject *obj, value v) @@ -259,11 +269,11 @@ int py_loader_impl_finalizer_object(loader_impl impl, PyObject *obj, value v) if (destructor != NULL) { /* This will destroy the capsule too */ - Py_DECREF(destructor); + Py_DecRef(destructor); } else { - Py_XDECREF(v_capsule); + Py_DecRef(v_capsule); } py_loader_thread_release(); @@ -281,7 +291,7 @@ PyObject *py_loader_impl_capsule_new_null(void) /* We want to create a new capsule with contents set to NULL, but PyCapsule * does not allow that, instead we are going to identify our NULL capsule with * this configuration (setting the capsule to Py_None) */ - return PyCapsule_New(Py_None, py_loader_capsule_null_id, NULL); + return PyCapsule_New((void *)Py_NonePtr(), py_loader_capsule_null_id, NULL); } void py_loader_impl_value_invoke_state_finalize(value v, void *data) @@ -293,9 +303,7 @@ void py_loader_impl_value_invoke_state_finalize(value v, void *data) if (loader_is_destroyed(invoke_state->impl) != 0 && capsule != NULL) { - py_loader_thread_acquire(); - Py_DECREF(capsule); - py_loader_thread_release(); + py_loader_thread_delayed_destroy(capsule); } free(invoke_state); @@ -313,10 +321,9 @@ void py_loader_impl_value_ptr_finalize(value v, void *data) if (loader_is_destroyed(impl) != 0) { - py_loader_thread_acquire(); PyObject *obj = (PyObject *)value_to_ptr(v); - Py_XDECREF(obj); - py_loader_thread_release(); + + py_loader_thread_delayed_destroy(obj); } } } @@ -339,7 +346,7 @@ void type_py_interface_destroy(type t, type_impl impl) if (Py_IsInitialized() != 0) { py_loader_thread_acquire(); - Py_DECREF(builtin); + Py_DecRef(builtin); py_loader_thread_release(); } } @@ -402,9 +409,7 @@ void future_py_interface_destroy(future f, future_impl impl) { if (loader_is_destroyed(py_future->impl) != 0) { - py_loader_thread_acquire(); - Py_DECREF(py_future->future); - py_loader_thread_release(); + py_loader_thread_delayed_destroy(py_future->future); } free(py_future); @@ -446,10 +451,10 @@ value py_object_interface_get(object obj, object_impl impl, struct accessor_type PyObject *pyobject_object = py_object->obj; PyObject *key_py_str = PyUnicode_FromString(attribute_name(accessor->data.attr)); PyObject *generic_attr = PyObject_GenericGetAttr(pyobject_object, key_py_str); - Py_XDECREF(key_py_str); + Py_DecRef(key_py_str); value v = py_loader_impl_capi_to_value(impl, generic_attr, py_loader_impl_capi_to_value_type(py_object->impl, generic_attr)); - Py_XDECREF(generic_attr); + Py_DecRef(generic_attr); py_loader_thread_release(); @@ -468,7 +473,7 @@ int py_object_interface_set(object obj, object_impl impl, struct accessor_type * PyObject *pyvalue = py_loader_impl_value_to_capi(py_object->impl, value_type_id(v), v); int retval = PyObject_GenericSetAttr(pyobject_object, key_py_str, pyvalue); - Py_DECREF(key_py_str); + Py_DecRef(key_py_str); py_loader_thread_release(); @@ -504,7 +509,7 @@ value py_object_interface_method_invoke(object obj, object_impl impl, method m, PyObject *python_object = PyObject_CallMethod(obj_impl->obj, method_name(m), "O", args_tuple, NULL); - Py_DECREF(args_tuple); + Py_DecRef(args_tuple); if (python_object == NULL) { @@ -513,7 +518,7 @@ value py_object_interface_method_invoke(object obj, object_impl impl, method m, ret = py_loader_impl_capi_to_value(impl, python_object, py_loader_impl_capi_to_value_type(obj_impl->impl, python_object)); - Py_XDECREF(python_object); + Py_DecRef(python_object); release: py_loader_thread_release(); @@ -556,18 +561,17 @@ void py_object_interface_destroy(object obj, object_impl impl) { if (loader_is_destroyed(py_object->impl) != 0) { - py_loader_thread_acquire(); - - Py_XDECREF(py_object->obj); - - py_loader_thread_release(); - - if (py_object->obj_class != NULL) + if (py_object->obj != NULL) { - value_type_destroy(py_object->obj_class); + py_loader_thread_delayed_destroy(py_object->obj); } } + if (py_object->obj_class != NULL) + { + value_type_destroy(py_object->obj_class); + } + free(py_object); } } @@ -637,7 +641,7 @@ object py_class_interface_constructor(klass cls, class_impl impl, const char *na /* Calling the class will create an instance (object) */ PyObject *python_object = PyObject_CallObject(py_cls->cls, args_tuple); - Py_DECREF(args_tuple); + Py_DecRef(args_tuple); if (python_object == NULL) { @@ -646,7 +650,7 @@ object py_class_interface_constructor(klass cls, class_impl impl, const char *na return NULL; } - Py_INCREF(py_cls->cls); + Py_IncRef(py_cls->cls); py_loader_thread_release(); py_obj->obj = python_object; @@ -670,10 +674,10 @@ value py_class_interface_static_get(klass cls, class_impl impl, struct accessor_ PyObject *key_py_str = PyUnicode_FromString(attr_name); PyObject *generic_attr = PyObject_GenericGetAttr(pyobject_class, key_py_str); - Py_XDECREF(key_py_str); + Py_DecRef(key_py_str); value v = py_loader_impl_capi_to_value(impl, generic_attr, py_loader_impl_capi_to_value_type(py_class->impl, generic_attr)); - Py_XDECREF(generic_attr); + Py_DecRef(generic_attr); py_loader_thread_release(); @@ -685,7 +689,6 @@ int py_class_interface_static_set(klass cls, class_impl impl, struct accessor_ty (void)cls; loader_impl_py_class py_class = (loader_impl_py_class)impl; - PyObject *pyobject_class = py_class->cls; char *attr_name = attribute_name(accessor->data.attr); if (attr_name == NULL) @@ -695,15 +698,15 @@ int py_class_interface_static_set(klass cls, class_impl impl, struct accessor_ty py_loader_thread_acquire(); - PyObject *pyvalue = py_loader_impl_value_to_capi(py_class->impl, value_type_id(v), v); + PyObject *py_value = py_loader_impl_value_to_capi(py_class->impl, value_type_id(v), v); PyObject *key_py_str = PyUnicode_FromString(attr_name); - int retval = PyObject_GenericSetAttr(pyobject_class, key_py_str, pyvalue); + int result = PyObject_SetAttr(py_class->cls, key_py_str, py_value); - Py_DECREF(key_py_str); + Py_DecRef(key_py_str); py_loader_thread_release(); - return retval; + return result; } value py_class_interface_static_invoke(klass cls, class_impl impl, method m, class_args args, size_t argc) @@ -743,8 +746,8 @@ value py_class_interface_static_invoke(klass cls, class_impl impl, method m, cla PyObject *python_object = PyObject_Call(method, args_tuple, NULL); - Py_DECREF(args_tuple); - Py_DECREF(method); + Py_DecRef(args_tuple); + Py_DecRef(method); if (python_object == NULL) { @@ -783,9 +786,7 @@ void py_class_interface_destroy(klass cls, class_impl impl) { if (loader_is_destroyed(py_class->impl) != 0) { - py_loader_thread_acquire(); - Py_XDECREF(py_class->cls); - py_loader_thread_release(); + py_loader_thread_delayed_destroy(py_class->cls); } free(py_class); @@ -811,13 +812,13 @@ int py_loader_impl_check_future(loader_impl_py py_impl, PyObject *obj) { PyObject *args_tuple = PyTuple_New(1); - Py_INCREF(obj); + Py_IncRef(obj); PyTuple_SetItem(args_tuple, 0, obj); PyObject *result = PyObject_Call(py_impl->thread_background_future_check, args_tuple, NULL); - Py_XDECREF(args_tuple); + Py_DecRef(args_tuple); if (result == NULL) { @@ -831,7 +832,7 @@ int py_loader_impl_check_future(loader_impl_py py_impl, PyObject *obj) int ret = PyObject_IsTrue(result); - Py_DECREF(result); + Py_DecRef(result); return ret; } @@ -852,7 +853,7 @@ int py_loader_impl_check_async(loader_impl_py py_impl, PyObject *func) int ret = PyObject_IsTrue(result); - Py_DECREF(result); + Py_DecRef(result); return ret; } @@ -869,7 +870,7 @@ int py_loader_impl_check_class(loader_impl_py py_impl, PyObject *obj) int result = !(PyObject_IsTrue(is_class) == 1); - Py_DECREF(is_class); + Py_DecRef(is_class); return result; } @@ -928,7 +929,7 @@ type_id py_loader_impl_capi_to_value_type(loader_impl impl, PyObject *obj) { return TYPE_FUNCTION; } - else if (obj == Py_None) + else if (obj == Py_NonePtr()) { return TYPE_NULL; } @@ -1156,7 +1157,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) const char *name = PyCapsule_GetName(obj); void *ptr = PyCapsule_GetPointer(obj, name); - if (ptr == Py_None && name == py_loader_capsule_null_id) + if (ptr == Py_NonePtr() && name == py_loader_capsule_null_id) { v = value_create_ptr(NULL); } @@ -1180,7 +1181,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) /* Move finalizers */ value_move(callback, invoke_state->callback); - Py_DECREF(invoke_state_capsule); + Py_DecRef(invoke_state_capsule); return callback; } @@ -1196,7 +1197,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) return NULL; } - Py_INCREF(obj); + Py_IncRef(obj); py_func->func = obj; py_func->impl = impl; @@ -1241,7 +1242,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) py_future->py_impl = py_impl; py_future->future = obj; - Py_INCREF(obj); + Py_IncRef(obj); v = value_create_future(f); } @@ -1249,11 +1250,11 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) { loader_impl_py_class py_cls = malloc(sizeof(struct loader_impl_py_class_type)); - Py_INCREF(obj); + Py_IncRef(obj); PyObject *qualname = PyObject_GetAttrString(obj, "__qualname__"); klass c = class_create(PyUnicode_AsUTF8(qualname), ACCESSOR_TYPE_STATIC, py_cls, &py_class_interface_singleton); - Py_XDECREF(qualname); + Py_DecRef(qualname); py_cls->impl = impl; py_cls->cls = obj; @@ -1273,7 +1274,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) { loader_impl_py_object py_obj = malloc(sizeof(struct loader_impl_py_object_type)); - Py_INCREF(obj); + Py_IncRef(obj); PyObject *object_class = PyObject_Type(obj); /* Increments the class reference count */ @@ -1283,7 +1284,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) /* So we must avoid calling it's constructor again */ PyObject *repr = PyObject_Repr(obj); object o = object_create(PyUnicode_AsUTF8(repr), ACCESSOR_TYPE_STATIC, py_obj, &py_object_interface_singleton, value_to_class(obj_cls)); - Py_XDECREF(repr); + Py_DecRef(repr); py_obj->impl = impl; py_obj->obj = obj; @@ -1303,9 +1304,9 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) { PyObject *tb = PyException_GetTraceback(obj); - v = py_loader_impl_error_value_from_exception(loader_impl_get(impl), (PyObject *)Py_TYPE(obj), obj, tb ? tb : Py_None); + v = py_loader_impl_error_value_from_exception(loader_impl_get(impl), (PyObject *)Py_TYPE(obj), obj, tb ? tb : Py_NonePtr()); - Py_XDECREF(tb); + Py_DecRef(tb); } else { @@ -1313,7 +1314,7 @@ value py_loader_impl_capi_to_value(loader_impl impl, PyObject *obj, type_id id) v = value_create_ptr(obj); /* Create reference to the value so it does not get garbage collected */ - Py_INCREF(obj); + Py_IncRef(obj); /* Set up finalizer in order to free the value */ value_finalizer(v, &py_loader_impl_value_ptr_finalize, impl); @@ -1462,7 +1463,7 @@ PyObject *py_loader_impl_value_to_capi(loader_impl impl, type_id id, value v) { /* TODO */ log_write("metacall", LOG_LEVEL_ERROR, "TODO: Python future not implemented yet for arguments"); - Py_RETURN_NONE; + return Py_ReturnNone(); } else if (id == TYPE_FUNCTION) { @@ -1481,7 +1482,7 @@ PyObject *py_loader_impl_value_to_capi(loader_impl impl, type_id id, value v) invoke_state_capsule = PyCapsule_New(invoke_state, NULL, NULL); - Py_XINCREF(invoke_state_capsule); + Py_IncRef(invoke_state_capsule); /* Set up finalizer in order to free the invoke state */ value_finalizer(invoke_state->callback, &py_loader_impl_value_invoke_state_finalize, invoke_state_capsule); @@ -1490,7 +1491,7 @@ PyObject *py_loader_impl_value_to_capi(loader_impl impl, type_id id, value v) } else if (id == TYPE_NULL) { - Py_RETURN_NONE; + return Py_ReturnNone(); } else if (id == TYPE_CLASS) { @@ -1517,7 +1518,7 @@ PyObject *py_loader_impl_value_to_capi(loader_impl impl, type_id id, value v) /* TODO: The return value of object_impl_get may not be a loader_impl_py_object, it can be a loader_impl_node_node too */ /* TODO: We must detect if it comes from python and use this method, otherwise we must create the object dynamically */ loader_impl_py_object obj_impl = object_impl_get(obj); - Py_INCREF(obj_impl->obj); + Py_IncRef(obj_impl->obj); if (obj_impl == NULL) { @@ -1548,18 +1549,18 @@ PyObject *py_task_callback_handler_impl(PyObject *self, PyObject *pyfuture) { py_loader_thread_release(); log_write("metacall", LOG_LEVEL_ERROR, "Invalid python capsule in task_callback_handler"); - Py_RETURN_NONE; + return Py_ReturnNone(); } loader_impl_py_await_invoke_callback_state callback_state = PyCapsule_GetPointer(capsule, NULL); - Py_DECREF(capsule); + Py_DecRef(capsule); /* pyfuture should never raise InvalidStateError exception here */ /* because this is a callback set in Future.add_done_callback */ PyObject *result_str = PyUnicode_FromString("result"); PyObject *result = PyObject_CallMethodObjArgs(pyfuture, result_str, NULL); - Py_DECREF(result_str); + Py_DecRef(result_str); value v = NULL, ret = NULL; @@ -1568,7 +1569,7 @@ PyObject *py_task_callback_handler_impl(PyObject *self, PyObject *pyfuture) type_id id = py_loader_impl_capi_to_value_type(callback_state->impl, result); v = py_loader_impl_capi_to_value(callback_state->impl, result, id); - Py_DECREF(result); + Py_DecRef(result); py_loader_thread_release(); ret = callback_state->resolve_callback(v, callback_state->context); @@ -1592,7 +1593,7 @@ PyObject *py_task_callback_handler_impl(PyObject *self, PyObject *pyfuture) v = py_loader_impl_capi_to_value(callback_state->impl, val, id); } - Py_XDECREF(args); + Py_DecRef(args); PyErr_Clear(); } @@ -1609,7 +1610,7 @@ PyObject *py_task_callback_handler_impl(PyObject *self, PyObject *pyfuture) loader_impl impl = callback_state->impl; - Py_DECREF(callback_state->coroutine); + Py_DecRef(callback_state->coroutine); py_loader_thread_release(); @@ -1619,7 +1620,7 @@ PyObject *py_task_callback_handler_impl(PyObject *self, PyObject *pyfuture) if (ret == NULL) { - Py_RETURN_NONE; + return Py_ReturnNone(); } else { @@ -1683,7 +1684,7 @@ function_return function_py_interface_invoke(function func, function_impl impl, } } - Py_XDECREF(tuple_args); + Py_DecRef(tuple_args); if (is_var_args) { @@ -1698,7 +1699,7 @@ function_return function_py_interface_invoke(function func, function_impl impl, type_id id = ret_type == NULL ? py_loader_impl_capi_to_value_type(py_func->impl, result) : type_index(ret_type); v = py_loader_impl_capi_to_value(py_func->impl, result, id); - Py_DECREF(result); + Py_DecRef(result); finalize: py_loader_thread_release(); return v; @@ -1750,7 +1751,7 @@ function_return function_py_interface_await(function func, function_impl impl, f if (coroutine == NULL || PyErr_Occurred() != NULL) { - Py_XDECREF(coroutine); + Py_DecRef(coroutine); goto error; } @@ -1759,7 +1760,7 @@ function_return function_py_interface_await(function func, function_impl impl, f if (args_tuple == NULL) { - Py_DECREF(coroutine); + Py_DecRef(coroutine); goto error; } @@ -1768,8 +1769,8 @@ function_return function_py_interface_await(function func, function_impl impl, f if (callback_state == NULL) { - Py_DECREF(coroutine); - Py_DECREF(args_tuple); + Py_DecRef(coroutine); + Py_DecRef(args_tuple); goto error; } @@ -1783,8 +1784,8 @@ function_return function_py_interface_await(function func, function_impl impl, f if (callback_status == NULL) { - Py_DECREF(coroutine); - Py_DECREF(args_tuple); + Py_DecRef(coroutine); + Py_DecRef(args_tuple); free(callback_state); goto error; } @@ -1792,10 +1793,10 @@ function_return function_py_interface_await(function func, function_impl impl, f /* Create a reference to the function so we avoid to delete it when destroying the event loop */ callback_state->func_val = value_create_function(func); - Py_INCREF(py_impl->asyncio_loop); - Py_INCREF(coroutine); - Py_INCREF(py_impl->py_task_callback_handler); - Py_INCREF(callback_status); + Py_IncRef(py_impl->asyncio_loop); + Py_IncRef(coroutine); + Py_IncRef(py_impl->py_task_callback_handler); + Py_IncRef(callback_status); PyTuple_SetItem(args_tuple, 0, py_impl->asyncio_loop); PyTuple_SetItem(args_tuple, 1, coroutine); @@ -1803,7 +1804,7 @@ function_return function_py_interface_await(function func, function_impl impl, f PyTuple_SetItem(args_tuple, 3, callback_status); pyfuture = PyObject_Call(py_impl->thread_background_send, args_tuple, NULL); - Py_DECREF(args_tuple); + Py_DecRef(args_tuple); /* Variable arguments */ if (args_size > signature_args_size) @@ -1828,8 +1829,8 @@ function_return function_py_interface_await(function func, function_impl impl, f v = py_loader_impl_capi_to_value(py_func->impl, pyfuture, id); - Py_DECREF(pyfuture); - Py_DECREF(tuple_args); + Py_DecRef(pyfuture); + Py_DecRef(tuple_args); py_loader_thread_release(); @@ -1842,8 +1843,8 @@ function_return function_py_interface_await(function func, function_impl impl, f py_loader_impl_error_print(py_impl); } - Py_XDECREF(pyfuture); - Py_DECREF(tuple_args); + Py_DecRef(pyfuture); + Py_DecRef(tuple_args); py_loader_thread_release(); @@ -1864,9 +1865,7 @@ void function_py_interface_destroy(function func, function_impl impl) if (loader_is_destroyed(py_func->impl) != 0) { - py_loader_thread_acquire(); - Py_DECREF(py_func->func); - py_loader_thread_release(); + py_loader_thread_delayed_destroy(py_func->func); } free(py_func); @@ -1897,7 +1896,7 @@ PyObject *py_loader_impl_function_type_invoke(PyObject *self, PyObject *args) { log_write("metacall", LOG_LEVEL_ERROR, "Fatal error when invoking a function, state cannot be recovered, avoiding the function call"); py_loader_thread_release(); - Py_RETURN_NONE; + return Py_ReturnNone(); } Py_ssize_t callee_args_size = PyTuple_Size(args); @@ -1908,7 +1907,7 @@ PyObject *py_loader_impl_function_type_invoke(PyObject *self, PyObject *args) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid allocation of arguments for callback"); py_loader_thread_release(); - Py_RETURN_NONE; + return Py_ReturnNone(); } /* Generate metacall values from python values */ @@ -1957,28 +1956,12 @@ PyObject *py_loader_impl_function_type_invoke(PyObject *self, PyObject *args) return py_ret; } - Py_RETURN_NONE; -} - -PyObject *py_loader_impl_get_builtin(loader_impl_py py_impl, const char *builtin_name) -{ - PyObject *builtin = PyObject_GetAttrString(py_impl->builtins_module, builtin_name); - - Py_XINCREF(builtin); - - if (builtin != NULL && PyType_Check(builtin)) - { - return builtin; - } - - Py_XDECREF(builtin); - - return NULL; + return Py_ReturnNone(); } int py_loader_impl_get_builtin_type(loader_impl impl, loader_impl_py py_impl, type_id id, const char *name) { - PyObject *builtin = py_loader_impl_get_builtin(py_impl, name); + PyObject *builtin = PyObject_GetAttrString(py_impl->builtins_module, name); if (builtin == NULL) { @@ -1992,26 +1975,26 @@ int py_loader_impl_get_builtin_type(loader_impl impl, loader_impl_py py_impl, ty goto error_create_type; } - if (loader_impl_type_define(impl, type_name(builtin_type), builtin_type) == 0) + if (loader_impl_type_define(impl, type_name(builtin_type), builtin_type) != 0) { - return 0; + goto error_define_type; } + return 0; + +error_define_type: type_destroy(builtin_type); error_create_type: - Py_DECREF(builtin); + Py_DecRef(builtin); error_get_builtin: return 1; } -int py_loader_impl_import_module(loader_impl_py py_impl, PyObject **loc, const char *name) +int py_loader_impl_import_module(loader_impl_py py_impl, PyObject **module, const char *name) { - PyObject *module_name = PyUnicode_DecodeFSDefault(name); - *loc = PyImport_Import(module_name); + *module = PyImport_ImportModule(name); - Py_DECREF(module_name); - - if (*loc == NULL) + if (*module == NULL) { py_loader_impl_error_print(py_impl); return 1; @@ -2070,7 +2053,7 @@ int py_loader_impl_initialize_inspect_types(loader_impl impl, loader_impl_py py_ return 0; error_get_builtin_type: - Py_DECREF(py_impl->builtins_module); + Py_DecRef(py_impl->builtins_module); error_import_module: return 1; } @@ -2122,27 +2105,27 @@ int py_loader_impl_initialize_inspect(loader_impl impl, loader_impl_py py_impl) return 0; } - Py_DECREF(py_impl->inspect_isclass); + Py_DecRef(py_impl->inspect_isclass); error_inspect_isclass: - Py_DECREF(py_impl->inspect_ismethod); + Py_DecRef(py_impl->inspect_ismethod); error_inspect_ismethod: - Py_DECREF(py_impl->inspect_getfullargspec); + Py_DecRef(py_impl->inspect_getfullargspec); error_inspect_getfullargspec: - Py_DECREF(py_impl->inspect_getattr_static); + Py_DecRef(py_impl->inspect_getattr_static); error_inspect_getattr_static: - Py_DECREF(py_impl->inspect_signature); + Py_DecRef(py_impl->inspect_signature); error_inspect_signature: - Py_DECREF(py_impl->inspect_module); + Py_DecRef(py_impl->inspect_module); error_import_module: return 1; } -int py_loader_impl_initialize_asyncio_module(loader_impl_py py_impl) +int py_loader_impl_initialize_asyncio_module(loader_impl_py py_impl, const int host) { PyObject *module_name = PyUnicode_DecodeFSDefault("asyncio"); py_impl->asyncio_module = PyImport_Import(module_name); - Py_DECREF(module_name); + Py_DecRef(module_name); if (PyErr_Occurred() != NULL) { @@ -2181,9 +2164,11 @@ int py_loader_impl_initialize_asyncio_module(loader_impl_py py_impl) } /* Start the asyncio thread */ - PyObject *args_tuple = PyTuple_New(0); - py_impl->asyncio_loop = PyObject_Call(py_impl->thread_background_start, args_tuple, NULL); - Py_XDECREF(args_tuple); + { + PyObject *args_tuple = PyTuple_New(0); + py_impl->asyncio_loop = PyObject_Call(py_impl->thread_background_start, args_tuple, NULL); + Py_DecRef(args_tuple); + } if (py_impl->asyncio_loop == NULL) { @@ -2191,14 +2176,25 @@ int py_loader_impl_initialize_asyncio_module(loader_impl_py py_impl) goto error_after_py_task_callback_handler; } + /* When running in host, we must register a thread atexit for finalizing the background threads + before Python_AtExit, just before when all threads are join (except by daemon threads) */ + if (host == 1) + { + PyObject *args_tuple = PyTuple_New(1); + Py_IncRef(py_impl->asyncio_loop); + PyTuple_SetItem(args_tuple, 0, py_impl->asyncio_loop); + PyObject_Call(py_impl->thread_background_register_atexit, args_tuple, NULL); + Py_DecRef(args_tuple); + } + return 0; error_after_py_task_callback_handler: - Py_DECREF(py_impl->py_task_callback_handler); + Py_DecRef(py_impl->py_task_callback_handler); error_after_asyncio_iscoroutinefunction: - Py_DECREF(py_impl->asyncio_iscoroutinefunction); + Py_DecRef(py_impl->asyncio_iscoroutinefunction); error_after_asyncio_module: - Py_DECREF(py_impl->asyncio_module); + Py_DecRef(py_impl->asyncio_module); return 1; } @@ -2224,16 +2220,18 @@ int py_loader_impl_initialize_traceback(loader_impl impl, loader_impl_py py_impl return 0; } - Py_XDECREF(py_impl->traceback_format_exception); + Py_DecRef(py_impl->traceback_format_exception); error_format_exception: - Py_DECREF(py_impl->traceback_module); + Py_DecRef(py_impl->traceback_module); error_import_module: return 1; } +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED int py_loader_impl_initialize_gc(loader_impl_py py_impl) { -#if DEBUG_ENABLED + PyObject *flags; + if (py_loader_impl_import_module(py_impl, &py_impl->gc_module, "gc") != 0) { goto error_import_module; @@ -2252,33 +2250,55 @@ int py_loader_impl_initialize_gc(loader_impl_py py_impl) } py_impl->gc_debug_leak = PyDict_GetItemString(PyModule_GetDict(py_impl->gc_module), "DEBUG_LEAK"); + + if (py_impl->gc_debug_leak == NULL) + { + goto error_callable_check; + } + + Py_IncRef(py_impl->gc_debug_leak); + py_impl->gc_debug_stats = PyDict_GetItemString(PyModule_GetDict(py_impl->gc_module), "DEBUG_STATS"); - if (py_impl->gc_debug_leak != NULL && py_impl->gc_debug_stats != NULL) + if (py_impl->gc_debug_stats == NULL) { - Py_INCREF(py_impl->gc_debug_leak); - Py_INCREF(py_impl->gc_debug_stats); + goto error_debug_leak; + } - return 0; + Py_IncRef(py_impl->gc_debug_stats); + + flags = PyNumber_Or(py_impl->gc_debug_leak, py_impl->gc_debug_stats); + + if (flags == NULL) + { + goto error_debug_stats; + } + + PyObject_CallFunctionObjArgs(py_impl->gc_set_debug, flags, NULL); + + Py_DecRef(flags); + + if (PyErr_Occurred() != NULL) + { + goto error_call_set_debug; } - Py_XDECREF(py_impl->gc_debug_leak); - Py_XDECREF(py_impl->gc_debug_stats); + return 0; +error_call_set_debug: + py_loader_impl_error_print(py_impl); +error_debug_stats: + Py_DecRef(py_impl->gc_debug_stats); +error_debug_leak: + Py_DecRef(py_impl->gc_debug_leak); error_callable_check: - Py_XDECREF(py_impl->gc_set_debug); + Py_DecRef(py_impl->gc_set_debug); error_set_debug: - Py_DECREF(py_impl->gc_module); + Py_DecRef(py_impl->gc_module); error_import_module: return 1; -#else - { - (void)py_impl; - - return 1; - } -#endif } +#endif int py_loader_impl_initialize_import(loader_impl_py py_impl) { @@ -2370,7 +2390,7 @@ int py_loader_impl_initialize_import(loader_impl_py py_impl) return 0; error_import_function: - Py_DECREF(py_impl->import_module); + Py_DecRef(py_impl->import_module); error_import_compile: py_loader_impl_error_print(py_impl); return 1; @@ -2380,8 +2400,15 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) { static const char thread_background_module_str[] = "import asyncio\n" - "from threading import Thread\n" - "from threading import Event\n" + "import threading\n" + "import sys\n" +#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}\", flush=True)\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" @@ -2396,13 +2423,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 = 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" @@ -2410,9 +2450,26 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) " task.__metacall_capsule = capsule\n" " task.add_done_callback(callback)\n" " return asyncio.wrap_future(task, loop=tl.loop)\n" - "def stop_background_loop(tl):\n" + /* 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" - " tl.t.join()\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" + "def register_atexit_background_loop(tl):\n" + " threading._register_atexit(atexit_background_loop, tl)\n"; /* How to use the module: */ /* @@ -2481,18 +2538,28 @@ int py_loader_impl_initialize_thread_background_module(loader_impl_py py_impl) goto error_thread_background_stop; } + py_impl->thread_background_register_atexit = PyObject_GetAttrString(py_impl->thread_background_module, "register_atexit_background_loop"); + + if (py_impl->thread_background_register_atexit == NULL || !PyCallable_Check(py_impl->thread_background_register_atexit)) + { + log_write("metacall", LOG_LEVEL_ERROR, "Error getting register_atexit_background_loop function"); + goto error_thread_background_register_atexit; + } + return 0; +error_thread_background_register_atexit: + Py_DecRef(py_impl->thread_background_register_atexit); error_thread_background_stop: - Py_XDECREF(py_impl->thread_background_stop); + Py_DecRef(py_impl->thread_background_stop); error_thread_background_send: - Py_XDECREF(py_impl->thread_background_send); + Py_DecRef(py_impl->thread_background_send); error_thread_background_start: - Py_XDECREF(py_impl->thread_background_start); + Py_DecRef(py_impl->thread_background_start); error_thread_background_future_check: - Py_XDECREF(py_impl->thread_background_future_check); + Py_DecRef(py_impl->thread_background_future_check); error_thread_background_compile: - Py_XDECREF(py_impl->thread_background_module); + Py_DecRef(py_impl->thread_background_module); if (PyErr_Occurred() != NULL) { @@ -2522,7 +2589,7 @@ int py_loader_impl_initialize_sys_executable(loader_impl_py py_impl) int result = PySys_SetObject("executable", exe_path_obj); - Py_DECREF(exe_path_obj); + Py_DecRef(exe_path_obj); if (result == -1) { @@ -2556,7 +2623,7 @@ int py_loader_impl_initialize_argv(loader_impl_py py_impl, int argc, char **argv int result = PySys_SetObject("argv", list); - Py_DECREF(list); + Py_DecRef(list); if (result == -1) { @@ -2572,13 +2639,18 @@ int py_loader_impl_initialize_argv(loader_impl_py py_impl, int argc, char **argv return 0; error_set_item: - Py_DECREF(list); + Py_DecRef(list); return 1; } 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) @@ -2592,11 +2664,12 @@ 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(); - Py_DECREF(invoke_state_capsule); + Py_DecRef(invoke_state_capsule); PyErr_Restore(error_type, error_value, error_traceback); } @@ -2604,49 +2677,65 @@ 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) { + const int host = loader_impl_get_option_host(impl); + (void)impl; (void)config; 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; if (py_impl == NULL) { goto error_alloc_py_impl; } - Py_InitializeEx(0); - - if (Py_IsInitialized() == 0) + if (host == 0) { - goto error_init_py; - } + Py_InitializeEx(0); + + if (Py_IsInitialized() == 0) + { + goto error_init_py; + } #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION <= 6 - if (PyEval_ThreadsInitialized() == 0) + if (PyEval_ThreadsInitialized() == 0) + { + PyEval_InitThreads(); + } +#endif + } + + /* Initialize symbol fallback */ + if (py_loader_symbol_fallback_initialize(loader_impl_dependency(impl, "python")) != 0) { - PyEval_InitThreads(); + log_write("metacall", LOG_LEVEL_ERROR, "Failed to initialize the Python Loader Symbol Fallback mechanism"); + goto error_init_py; } -#endif - /* Hook the deallocation of PyCFunction */ - py_loader_impl_pycfunction_dealloc = PyCFunction_Type.tp_dealloc; - PyCFunction_Type.tp_dealloc = PyCFunction_dealloc; - PyType_Modified(&PyCFunction_Type); + /* Initialize threading */ + gil_release = py_loader_thread_initialize(host); + /* Initialize executable */ if (py_loader_impl_initialize_sys_executable(py_impl) != 0) { goto error_after_sys_executable; } + /* Initialize main arguments */ char **argv = metacall_argv(); int argc = metacall_argc(); @@ -2658,9 +2747,18 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi } py_loader_impl_main_module = argv[1]; - py_loader_impl_run_main = 0; + + /* If we are running on host, this means the main is already executed by the host, so we can skip it, + * otherwise if we are not in host and we run it for the first time, we can prepare the loader + * for running the main the first time + */ + if (host == 0) + { + py_loader_impl_run_main = 0; + } } + /* Initialize stack trace module */ if (py_loader_impl_initialize_traceback(impl, py_impl) != 0) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid traceback module creation"); @@ -2670,51 +2768,73 @@ 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 */ { - if (py_loader_impl_initialize_gc(py_impl) != 0) - { - PyObject_CallMethodObjArgs(py_impl->gc_module, py_impl->gc_set_debug, py_impl->gc_debug_leak /* py_impl->gc_debug_stats */); - gc_initialized = 0; - } - else + gc_initialized = py_loader_impl_initialize_gc(py_impl); + + if (gc_initialized != 0) { log_write("metacall", LOG_LEVEL_WARNING, "Invalid garbage collector module creation"); } } #endif + /* Initialize inspect module */ if (py_loader_impl_initialize_inspect(impl, py_impl) != 0) { goto error_after_traceback_and_gc; } + /* Initialize import module */ if (py_loader_impl_initialize_import(py_impl) != 0) { goto error_after_inspect; } - if (PY_LOADER_PORT_NAME_FUNC() == NULL) + /* Initialize port module */ + if (py_port_initialize() != 0) { goto error_after_import; } + /* Initialize thread module for supporting threaded async */ if (py_loader_impl_initialize_thread_background_module(py_impl) != 0) { goto error_after_import; } - if (py_loader_impl_initialize_asyncio_module(py_impl) != 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 */ if (py_loader_impl_dict_type_init() < 0) { goto error_after_asyncio_module; } - py_loader_thread_initialize(); + /* Hook the deallocation of PyCFunction */ + py_loader_impl_pycfunction_dealloc = PyCFunctionTypePtr()->tp_dealloc; + PyCFunctionTypePtr()->tp_dealloc = PyCFunction_dealloc; + + /* TODO: This does not work after 3.13, is it really needed for this hook? */ +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 13 + PyType_Modified(PyCFunctionTypePtr()); +#endif + + if (gil_release) + { + py_loader_thread_release(); + } /* Register initialization */ loader_initialization_register(impl); @@ -2724,41 +2844,46 @@ loader_impl_data py_loader_impl_initialize(loader_impl impl, configuration confi return py_impl; error_after_asyncio_module: - Py_DECREF(py_impl->asyncio_iscoroutinefunction); - Py_DECREF(py_impl->asyncio_loop); - Py_DECREF(py_impl->asyncio_module); - Py_XDECREF(py_impl->py_task_callback_handler); + Py_DecRef(py_impl->asyncio_iscoroutinefunction); + Py_DecRef(py_impl->asyncio_loop); + Py_DecRef(py_impl->asyncio_module); + Py_DecRef(py_impl->py_task_callback_handler); error_after_thread_background_module: - Py_DECREF(py_impl->thread_background_module); - Py_DECREF(py_impl->thread_background_start); - Py_DECREF(py_impl->thread_background_send); - Py_DECREF(py_impl->thread_background_stop); - Py_DECREF(py_impl->thread_background_future_check); + Py_DecRef(py_impl->thread_background_module); + Py_DecRef(py_impl->thread_background_start); + Py_DecRef(py_impl->thread_background_send); + Py_DecRef(py_impl->thread_background_stop); + Py_DecRef(py_impl->thread_background_register_atexit); + Py_DecRef(py_impl->thread_background_future_check); error_after_import: - Py_DECREF(py_impl->import_module); - Py_DECREF(py_impl->import_function); + Py_DecRef(py_impl->import_module); + Py_DecRef(py_impl->import_function); error_after_inspect: - Py_DECREF(py_impl->inspect_signature); - Py_DECREF(py_impl->inspect_module); - Py_DECREF(py_impl->builtins_module); + Py_DecRef(py_impl->inspect_signature); + Py_DecRef(py_impl->inspect_module); + Py_DecRef(py_impl->builtins_module); error_after_traceback_and_gc: if (traceback_initialized == 0) { - Py_DECREF(py_impl->traceback_format_exception); - Py_DECREF(py_impl->traceback_module); + 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); - Py_DECREF(py_impl->gc_debug_leak); - Py_DECREF(py_impl->gc_debug_stats); - Py_DECREF(py_impl->gc_module); + Py_DecRef(py_impl->gc_set_debug); + Py_DecRef(py_impl->gc_debug_leak); + Py_DecRef(py_impl->gc_debug_stats); + Py_DecRef(py_impl->gc_module); } #endif error_after_argv: error_after_sys_executable: - (void)py_loader_impl_finalize(py_impl); + if (gil_release) + { + py_loader_thread_release(); + } + (void)py_loader_impl_finalize(py_impl, host); error_init_py: free(py_impl); error_alloc_py_impl: @@ -2798,12 +2923,12 @@ 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 clear_current_path: - Py_DECREF(current_path); + Py_DecRef(current_path); py_loader_thread_release(); return result; } @@ -2855,18 +2980,18 @@ void py_loader_impl_module_destroy(loader_impl_py_handle_module module) if (item != NULL) { - Py_DECREF(item); + Py_DecRef(item); PyObject_DelItem(system_modules, module->name); } } - Py_DECREF(module->name); + Py_DecRef(module->name); module->name = NULL; } if (module->instance != NULL) { - Py_DECREF(module->instance); + Py_DecRef(module->instance); module->instance = NULL; } } @@ -2929,14 +3054,14 @@ int py_loader_impl_load_from_file_path(loader_impl_py py_impl, loader_impl_py_ha PyTuple_SetItem(args_tuple, 0, module->name); PyTuple_SetItem(args_tuple, 1, py_path); - Py_INCREF(module->name); - Py_INCREF(py_path); + Py_IncRef(module->name); + Py_IncRef(py_path); module->instance = PyObject_Call(py_impl->import_function, args_tuple, NULL); if (!(module->instance != NULL && PyModule_Check(module->instance))) { - if (module->instance != NULL && PyErr_GivenExceptionMatches(module->instance, PyExc_Exception)) + if (module->instance != NULL && PyExceptionInstance_Check(module->instance)) { *exception = module->instance; module->instance = NULL; @@ -2945,17 +3070,17 @@ int py_loader_impl_load_from_file_path(loader_impl_py py_impl, loader_impl_py_ha goto error_module_instance; } - Py_DECREF(args_tuple); - Py_DECREF(py_path); + Py_DecRef(args_tuple); + Py_DecRef(py_path); return 0; error_module_instance: - Py_DECREF(args_tuple); + Py_DecRef(args_tuple); error_tuple_create: - Py_DECREF(py_path); + Py_DecRef(py_path); error_path_create: - Py_XDECREF(module->name); + Py_DecRef(module->name); module->name = NULL; error_name_create: return 1; @@ -2987,13 +3112,13 @@ int py_loader_impl_load_from_module(loader_impl_py py_impl, loader_impl_py_handl } PyTuple_SetItem(args_tuple, 0, module->name); - Py_INCREF(module->name); + Py_IncRef(module->name); module->instance = PyObject_Call(py_impl->import_function, args_tuple, NULL); if (!(module->instance != NULL && PyModule_Check(module->instance))) { - if (module->instance != NULL && PyErr_GivenExceptionMatches(module->instance, PyExc_Exception)) + if (module->instance != NULL && PyExceptionInstance_Check(module->instance)) { *exception = module->instance; module->instance = NULL; @@ -3002,15 +3127,15 @@ int py_loader_impl_load_from_module(loader_impl_py py_impl, loader_impl_py_handl goto error_module_instance; } - Py_INCREF(module->instance); - Py_DECREF(args_tuple); + Py_IncRef(module->instance); + Py_DecRef(args_tuple); return 0; error_module_instance: - Py_DECREF(args_tuple); + Py_DecRef(args_tuple); error_tuple_create: - Py_XDECREF(module->name); + Py_DecRef(module->name); module->name = NULL; error_name_create: return 1; @@ -3018,7 +3143,7 @@ int py_loader_impl_load_from_module(loader_impl_py py_impl, loader_impl_py_handl int py_loader_impl_import_exception(PyObject *exception) { - return /*PyErr_GivenExceptionMatches(exception, PyExc_ImportError) ||*/ PyErr_GivenExceptionMatches(exception, PyExc_FileNotFoundError); + return /*PyErr_GivenExceptionMatches(exception, PyExc_ImportErrorPtr()) ||*/ PyErr_GivenExceptionMatches(exception, PyExc_FileNotFoundErrorPtr()); } int py_loader_impl_load_from_file_relative(loader_impl_py py_impl, loader_impl_py_handle_module module, const loader_path path, PyObject **exception, int run_main) @@ -3071,7 +3196,7 @@ static void py_loader_impl_load_from_file_exception(loader_impl_py py_impl, cons PyErr_SetObject(exception_type, exception); - Py_DECREF(exception_type); + Py_DecRef(exception_type); py_loader_impl_error_print(py_impl); @@ -3185,7 +3310,7 @@ loader_handle py_loader_impl_load_from_file(loader_impl impl, const loader_path py_loader_impl_error_print(py_impl); PyErr_Clear(); } - Py_XDECREF(exception); + Py_DecRef(exception); error_recursive_call: py_loader_thread_release(); py_loader_impl_handle_destroy(py_handle); @@ -3205,7 +3330,7 @@ PyObject *py_loader_impl_load_from_memory_compile(loader_impl_py py_impl, const PyObject *instance = PyImport_ExecCodeModule(name, compiled); - Py_DECREF(compiled); + Py_DecRef(compiled); return instance; } @@ -3324,7 +3449,7 @@ type py_loader_impl_discover_type(loader_impl impl, PyObject *annotation, const log_write("metacall", LOG_LEVEL_DEBUG, "Discover type (%p) (%p): %s", (void *)annotation, (void *)type_derived(t), annotation_name); } - Py_DECREF(annotation_qualname); + Py_DecRef(annotation_qualname); } return t; @@ -3368,9 +3493,9 @@ size_t py_loader_impl_discover_callable_args_count(loader_impl_py py_impl, PyObj args_count--; } - Py_DECREF(is_method); + Py_DecRef(is_method); clear_spec: - Py_DECREF(spec); /* The elements from the tuple (args) are cleaned here */ + Py_DecRef(spec); /* The elements from the tuple (args) are cleaned here */ unsupported_callable: return args_count; } @@ -3387,9 +3512,9 @@ int py_loader_impl_discover_func(loader_impl impl, PyObject *func, function f) } PyTuple_SetItem(args, 0, func); - Py_INCREF(func); + Py_IncRef(func); PyObject *result = PyObject_CallObject(py_impl->inspect_signature, args); - Py_DECREF(args); + Py_DecRef(args); if (result != NULL) { @@ -3430,21 +3555,21 @@ int py_loader_impl_discover_func(loader_impl impl, PyObject *func, function f) PyObject *annotation = PyObject_GetAttrString(parameter, "annotation"); type t = py_loader_impl_discover_type(impl, annotation, func_name, parameter_name); signature_set(s, iterator, parameter_name, t); - Py_XDECREF(name); - Py_XDECREF(annotation); + Py_DecRef(name); + Py_DecRef(annotation); } } - Py_XDECREF(parameter_list); + Py_DecRef(parameter_list); } - Py_XDECREF(parameters); + Py_DecRef(parameters); function_async(f, py_loader_impl_check_async(py_impl, func) == 1 ? ASYNCHRONOUS : SYNCHRONOUS); signature_set_return(s, py_loader_impl_discover_type(impl, return_annotation, func_name, NULL)); - Py_DECREF(return_annotation); + Py_DecRef(return_annotation); return 0; } @@ -3485,10 +3610,10 @@ int py_loader_impl_discover_method(loader_impl impl, PyObject *callable, method else { PyTuple_SetItem(args, 0, callable); - Py_INCREF(callable); + Py_IncRef(callable); } PyObject *result = PyObject_CallObject(py_impl->inspect_signature, args); - Py_DECREF(args); + Py_DecRef(args); if (result != NULL) { @@ -3529,19 +3654,19 @@ int py_loader_impl_discover_method(loader_impl impl, PyObject *callable, method PyObject *annotation = PyObject_GetAttrString(parameter, "annotation"); type t = py_loader_impl_discover_type(impl, annotation, m_name, parameter_name); signature_set(s, iterator, parameter_name, t); - Py_XDECREF(name); - Py_XDECREF(annotation); + Py_DecRef(name); + Py_DecRef(annotation); } } - Py_XDECREF(parameter_list); + Py_DecRef(parameter_list); } - Py_XDECREF(parameters); + Py_DecRef(parameters); signature_set_return(s, py_loader_impl_discover_type(impl, return_annotation, m_name, NULL)); - Py_DECREF(return_annotation); + Py_DecRef(return_annotation); return 0; } @@ -3598,14 +3723,14 @@ type py_loader_impl_get_type(loader_impl impl, PyObject *obj) t = NULL; } - Py_DECREF(t_name); + Py_DecRef(t_name); return t; } type_name_error: - Py_XDECREF(t_name); + Py_DecRef(t_name); builtin_error: - Py_XDECREF(builtin); + Py_DecRef(builtin); return t; } @@ -3630,12 +3755,12 @@ int py_loader_impl_discover_constructor(loader_impl impl, PyObject *py_class, kl PyObject *name_init = PyUnicode_FromString("__init__"); PyObject *init_method = PyObject_GenericGetAttr(py_class, name_init); - Py_DECREF(name_init); + Py_DecRef(name_init); PyTuple_SetItem(args, 0, init_method); PyObject *result = PyObject_CallObject(py_impl->inspect_signature, args); - Py_DECREF(args); /* Clears init_method reference */ + Py_DecRef(args); /* Clears init_method reference */ if (result == NULL) { @@ -3670,8 +3795,8 @@ int py_loader_impl_discover_constructor(loader_impl impl, PyObject *py_class, kl PyObject *annotation = PyObject_GetAttrString(parameter, "annotation"); type t = py_loader_impl_discover_type(impl, annotation, "__init__", parameter_name); constructor_set(ctor, parameter_count++, parameter_name, t); - Py_XDECREF(name); - Py_XDECREF(annotation); + Py_DecRef(name); + Py_DecRef(annotation); } ret = class_register_constructor(c, ctor); @@ -3682,10 +3807,10 @@ int py_loader_impl_discover_constructor(loader_impl impl, PyObject *py_class, kl } } - Py_XDECREF(parameter_list); + Py_DecRef(parameter_list); } - Py_XDECREF(parameters); + Py_DecRef(parameters); return ret; } @@ -3709,12 +3834,12 @@ int py_loader_impl_discover_class(loader_impl impl, PyObject *py_class, klass c) { PyObject *nameobj = PyUnicode_FromString("__dict__"); PyObject *read_only_dict = PyObject_GenericGetAttr((PyObject *)py_class, nameobj); - Py_DECREF(nameobj); + Py_DecRef(nameobj); /* Turns out __dict__ is not a PyDict but PyMapping */ - if (!PyObject_TypeCheck(read_only_dict, &PyDictProxy_Type)) + if (!PyObject_TypeCheck(read_only_dict, PyDictProxyTypePtr())) { - Py_XDECREF(read_only_dict); + Py_DecRef(read_only_dict); return 1; } @@ -3749,12 +3874,12 @@ int py_loader_impl_discover_class(loader_impl impl, PyObject *py_class, klass c) } PyTuple_SetItem(args, 0, py_class); // class - Py_INCREF(py_class); + Py_IncRef(py_class); PyTuple_SetItem(args, 1, tuple_key); // method - Py_INCREF(tuple_key); + Py_IncRef(tuple_key); PyObject *method_static = PyObject_CallObject(py_impl->inspect_getattr_static, args); - Py_DECREF(args); - bool is_static_method = PyObject_TypeCheck(method_static, &PyStaticMethod_Type); + Py_DecRef(args); + bool is_static_method = PyObject_TypeCheck(method_static, PyStaticMethodTypePtr()); log_write("metacall", LOG_LEVEL_DEBUG, "Introspection: class member %s, type %s, static method: %d", PyUnicode_AsUTF8(tuple_key), @@ -3770,7 +3895,7 @@ int py_loader_impl_discover_class(loader_impl impl, PyObject *py_class, klass c) { PyObject *func = PyObject_GetAttrString(tuple_val, "__func__"); args_count = py_loader_impl_discover_callable_args_count(py_impl, func); - Py_DECREF(func); + Py_DecRef(func); } else { @@ -3808,7 +3933,7 @@ int py_loader_impl_discover_class(loader_impl impl, PyObject *py_class, klass c) } /* Delete the reference of the method here instead of in py_method_interface_destroy */ - Py_XDECREF(tuple_val); + Py_DecRef(tuple_val); } else { @@ -3830,8 +3955,8 @@ int py_loader_impl_discover_class(loader_impl impl, PyObject *py_class, klass c) } } - Py_XDECREF(dict_items); - Py_XDECREF(read_only_dict); + Py_DecRef(dict_items); + Py_DecRef(read_only_dict); } return 0; @@ -3880,8 +4005,8 @@ int py_loader_impl_discover_module(loader_impl impl, PyObject *module, context c while (PyDict_Next(module_dict, &position, &module_dict_key, &module_dict_val)) { // Class is also PyCallable, so test for class first - if (PyObject_TypeCheck(module_dict_val, &PyType_Type)) - // PyObject_IsSubclass(module_dict_val, (PyObject *)&PyType_Type) == 0 + if (PyObject_TypeCheck(module_dict_val, PyTypeTypePtr())) + // PyObject_IsSubclass(module_dict_val, (PyObject *)PyTypeTypePtr()) == 0 { const char *cls_name = PyUnicode_AsUTF8(module_dict_key); @@ -3889,7 +4014,7 @@ int py_loader_impl_discover_module(loader_impl impl, PyObject *module, context c loader_impl_py_class py_cls = malloc(sizeof(struct loader_impl_py_class_type)); - Py_INCREF(module_dict_val); + Py_IncRef(module_dict_val); klass c = class_create(cls_name, ACCESSOR_TYPE_STATIC, py_cls, &py_class_interface_singleton); @@ -3926,7 +4051,7 @@ int py_loader_impl_discover_module(loader_impl impl, PyObject *module, context c return 1; } - Py_INCREF(module_dict_val); + Py_IncRef(module_dict_val); py_func->func = module_dict_val; py_func->impl = impl; @@ -4017,9 +4142,9 @@ void py_loader_impl_error_print(loader_impl_py py_impl) log_write("metacall", LOG_LEVEL_ERROR, error_format_str, type_str, value_str, traceback_str ? traceback_str : traceback_not_found); - Py_XDECREF(traceback_list); - Py_DECREF(separator); - Py_XDECREF(traceback_str_obj); + Py_DecRef(traceback_list); + Py_DecRef(separator); + Py_DecRef(traceback_str_obj); PyErr_Restore(type, value, traceback); } @@ -4073,41 +4198,53 @@ value py_loader_impl_error_value_from_exception(loader_impl_py py_impl, PyObject ret = value_create_throwable(th); - Py_XDECREF(traceback_list); - Py_DECREF(separator); - Py_XDECREF(traceback_str_obj); + Py_DecRef(traceback_list); + Py_DecRef(separator); + Py_DecRef(traceback_str_obj); 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) { static const char garbage_format_str[] = "Python Garbage Collector:\n%s"; - static const char separator_str[] = "\n"; - - PyObject *garbage_list, *separator, *garbage_str_obj; + PyObject *garbage_repr, *garbage_list = PyObject_GetAttrString(py_impl->gc_module, "garbage"); + const char *garbage_str; - garbage_list = PyObject_GetAttrString(py_impl->gc_module, "garbage"); + if (garbage_list == NULL) + { + goto error_garbage_list; + } - #if PY_MAJOR_VERSION == 2 - separator = PyString_FromString(separator_str); + garbage_repr = PyObject_Repr(garbage_list); - garbage_str_obj = PyString_Join(separator, garbage_list); + if (garbage_repr == NULL) + { + goto error_garbage_repr; + } - log_write("metacall", LOG_LEVEL_DEBUG, garbage_format_str, PyString_AsString(garbage_str_obj)); - #elif PY_MAJOR_VERSION == 3 - separator = PyUnicode_FromString(separator_str); + garbage_str = PyUnicode_AsUTF8(garbage_repr); - garbage_str_obj = PyUnicode_Join(separator, garbage_list); + if (garbage_str == NULL) + { + goto error_garbage_str; + } - log_write("metacall", LOG_LEVEL_DEBUG, garbage_format_str, PyUnicode_AsUTF8(garbage_str_obj)); - #endif + log_write("metacall", LOG_LEVEL_DEBUG, garbage_format_str, garbage_str); - Py_DECREF(garbage_list); - Py_DECREF(separator); - Py_DECREF(garbage_str_obj); +error_garbage_str: + Py_DecRef(garbage_repr); +error_garbage_repr: + Py_DecRef(garbage_list); +error_garbage_list: + if (PyErr_Occurred() != NULL) + { + py_loader_impl_error_print(py_impl); + } } + #endif void py_loader_impl_sys_path_print(PyObject *sys_path_list) { @@ -4134,12 +4271,12 @@ void py_loader_impl_sys_path_print(PyObject *sys_path_list) log_write("metacall", LOG_LEVEL_DEBUG, sys_path_format_str, sys_path_str); - Py_XDECREF(sys_path_str_obj); - Py_XDECREF(separator); + Py_DecRef(sys_path_str_obj); + Py_DecRef(separator); } #endif -int py_loader_impl_finalize(loader_impl_py py_impl) +int py_loader_impl_finalize(loader_impl_py py_impl, const int host) { if (Py_IsInitialized() != 0) { @@ -4148,27 +4285,102 @@ int py_loader_impl_finalize(loader_impl_py py_impl) py_loader_impl_error_print(py_impl); } -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6 + if (host == 0) { +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6 if (Py_FinalizeEx() != 0) { log_write("metacall", LOG_LEVEL_DEBUG, "Error when executing Py_FinalizeEx"); return 1; } - } #else - { Py_Finalize(); - } #endif + } } 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); loader_impl_py py_impl = loader_impl_get(impl); + int result = 0; if (py_impl == NULL) { @@ -4181,53 +4393,76 @@ int py_loader_impl_destroy(loader_impl impl) py_loader_thread_acquire(); /* Stop event loop for async calls */ - PyObject *args_tuple = PyTuple_New(1); - Py_INCREF(py_impl->asyncio_loop); - PyTuple_SetItem(args_tuple, 0, py_impl->asyncio_loop); - PyObject_Call(py_impl->thread_background_stop, args_tuple, NULL); - Py_XDECREF(args_tuple); - - if (PyErr_Occurred() != NULL) +#if defined(WIN32) || defined(_WIN32) + if (py_loader_impl_check_thread(py_impl) == 0) +#endif { - py_loader_impl_error_print(py_impl); - } + PyObject *args_tuple = PyTuple_New(2); + Py_IncRef(py_impl->asyncio_loop); + PyTuple_SetItem(args_tuple, 0, py_impl->asyncio_loop); + /* If it is host, do not join the thread */ + PyTuple_SetItem(args_tuple, 1, PyBool_FromLong(!host)); + PyObject_Call(py_impl->thread_background_stop, args_tuple, NULL); + Py_DecRef(args_tuple); - Py_DECREF(py_impl->inspect_signature); - Py_DECREF(py_impl->inspect_getattr_static); - Py_DECREF(py_impl->inspect_getfullargspec); - Py_DECREF(py_impl->inspect_ismethod); - Py_DECREF(py_impl->inspect_isclass); - Py_DECREF(py_impl->inspect_module); - Py_DECREF(py_impl->builtins_module); - Py_DECREF(py_impl->traceback_format_exception); - Py_DECREF(py_impl->traceback_module); - Py_DECREF(py_impl->import_function); - Py_DECREF(py_impl->import_module); - - Py_XDECREF(py_impl->asyncio_iscoroutinefunction); - Py_XDECREF(py_impl->asyncio_loop); - Py_XDECREF(py_impl->asyncio_module); - Py_XDECREF(py_impl->py_task_callback_handler); - Py_XDECREF(py_impl->thread_background_future_check); - Py_XDECREF(py_impl->thread_background_module); - Py_XDECREF(py_impl->thread_background_start); - Py_XDECREF(py_impl->thread_background_send); - Py_XDECREF(py_impl->thread_background_stop); + if (PyErr_Occurred() != NULL) + { + py_loader_impl_error_print(py_impl); + } + } -#if DEBUG_ENABLED - { + /* Delete all the objects from the destructors of the other threads */ + py_loader_thread_destroy(); + + /* Destroy all Python loader objects */ + Py_DecRef(py_impl->inspect_signature); + Py_DecRef(py_impl->inspect_getattr_static); + Py_DecRef(py_impl->inspect_getfullargspec); + Py_DecRef(py_impl->inspect_ismethod); + Py_DecRef(py_impl->inspect_isclass); + Py_DecRef(py_impl->inspect_module); + Py_DecRef(py_impl->builtins_module); + Py_DecRef(py_impl->traceback_format_exception); + Py_DecRef(py_impl->traceback_module); + Py_DecRef(py_impl->import_function); + Py_DecRef(py_impl->import_module); + + Py_DecRef(py_impl->asyncio_iscoroutinefunction); + Py_DecRef(py_impl->asyncio_loop); + Py_DecRef(py_impl->asyncio_module); + Py_DecRef(py_impl->py_task_callback_handler); + Py_DecRef(py_impl->thread_background_future_check); + Py_DecRef(py_impl->thread_background_module); + Py_DecRef(py_impl->thread_background_start); + Py_DecRef(py_impl->thread_background_send); + Py_DecRef(py_impl->thread_background_stop); + Py_DecRef(py_impl->thread_background_register_atexit); + +#if DEBUG_ENABLED && DEBUG_PRINT_ENABLED + { + #if (defined(__ADDRESS_SANITIZER__) || defined(__MEMORY_SANITIZER__)) py_loader_impl_gc_print(py_impl); - Py_DECREF(py_impl->gc_set_debug); - Py_DECREF(py_impl->gc_debug_leak); - Py_DECREF(py_impl->gc_debug_stats); - Py_DECREF(py_impl->gc_module); + #endif + Py_DecRef(py_impl->gc_set_debug); + Py_DecRef(py_impl->gc_debug_leak); + Py_DecRef(py_impl->gc_debug_stats); + Py_DecRef(py_impl->gc_module); } #endif - int result = py_loader_impl_finalize(py_impl); + /* Destroy Python runtime itself (only when it is not the host) */ + result = py_loader_impl_finalize(py_impl, host); - /* Unhook the deallocation of PyCFunction */ - PyCFunction_Type.tp_dealloc = py_loader_impl_pycfunction_dealloc; + if (host == 0) + { + /* Unhook the deallocation of PyCFunction */ + PyCFunctionTypePtr()->tp_dealloc = py_loader_impl_pycfunction_dealloc; + } + else + { + /* On host, release the GIL and let Python continue until it calls Py_Finalize by itself */ + py_loader_thread_release(); + } free(py_impl); diff --git a/source/loaders/py_loader/source/py_loader_port.c b/source/loaders/py_loader/source/py_loader_port.c index 3ae0ac918a..8f60578e3b 100644 --- a/source/loaders/py_loader/source/py_loader_port.c +++ b/source/loaders/py_loader/source/py_loader_port.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,50 +23,13 @@ #include #include #include +#include #include #include -#ifndef PY_LOADER_PORT_NAME - #error "The Python Loader Port must be defined" -#endif - static const loader_tag py_loader_tag = "py"; -static PyObject *py_loader_port_none(void) -{ - Py_RETURN_NONE; -} - -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wstrict-aliasing" -#elif defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstrict-aliasing" -#elif defined(_MSC_VER) - #pragma warning(push) -// TODO -#endif - -static PyObject *py_loader_port_false(void) -{ - Py_RETURN_FALSE; -} - -static PyObject *py_loader_port_true(void) -{ - Py_RETURN_TRUE; -} - -#if defined(__clang__) - #pragma clang diagnostic pop -#elif defined(__GNUC__) - #pragma GCC diagnostic pop -#elif defined(_MSC_VER) - #pragma warning(pop) -#endif - static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *args, void **handle) { static const char format[] = "OO:metacall_load_from_file"; @@ -80,8 +43,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &tag, &paths)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_load_from_file('node', ['script.js']);"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_load_from_file('node', ['script.js']);"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -90,22 +53,22 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (!PyUnicode_Check(tag)) #endif { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); + return Py_ReturnFalse(); } if (!PyList_Check(paths)) { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in second argument (a list of strings indicating the paths must be used)"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in second argument (a list of strings indicating the paths must be used)"); + return Py_ReturnFalse(); } paths_size = PyList_Size(paths); if (paths_size == 0) { - PyErr_SetString(PyExc_TypeError, "At least one path must be included in the paths list"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "At least one path must be included in the paths list"); + return Py_ReturnFalse(); } /* Convert tag from unicode into a string */ @@ -124,8 +87,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (tag_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid tag string conversion"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid tag string conversion"); + return Py_ReturnFalse(); } /* Convert paths list into an array of strings */ @@ -133,8 +96,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (paths_str == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid argument allocation"); - return py_loader_port_false(); + PyErr_SetString(PyExc_ValueErrorPtr(), "Invalid argument allocation"); + return Py_ReturnFalse(); } for (iterator = 0; iterator < paths_size; ++iterator) @@ -168,8 +131,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid path string conversion"); - result = py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid path string conversion"); + result = Py_ReturnFalse(); goto clear; } @@ -177,8 +140,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (paths_str[iterator] == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid string path allocation"); - result = py_loader_port_false(); + PyErr_SetString(PyExc_ValueErrorPtr(), "Invalid string path allocation"); + result = Py_ReturnFalse(); goto clear; } @@ -197,7 +160,7 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (ret != 0) { - result = handle == NULL ? py_loader_port_false() : py_loader_port_none(); + result = handle == NULL ? Py_ReturnFalse() : Py_ReturnNone(); goto clear; } else @@ -214,8 +177,8 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar if (wrapper == NULL) { - Py_XDECREF(result); - result = py_loader_port_none(); + Py_DecRef(result); + result = Py_ReturnNone(); } else { @@ -224,7 +187,7 @@ static PyObject *py_loader_port_load_from_file_impl(PyObject *self, PyObject *ar } else { - result = py_loader_port_true(); + result = Py_ReturnTrue(); } } @@ -262,8 +225,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &tag, &path)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_load_from_package('cs', ['file.dll']);"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_load_from_package('cs', ['file.dll']);"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -272,8 +235,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (!PyUnicode_Check(tag)) #endif { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -282,8 +245,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (!PyUnicode_Check(path)) #endif { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in second argument (a string indicating the path must be used)"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in second argument (a string indicating the path must be used)"); + return Py_ReturnFalse(); } /* Convert tag from unicode into a string */ @@ -302,8 +265,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (tag_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid tag string conversion"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid tag string conversion"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -328,8 +291,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (path_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid path string conversion"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid path string conversion"); + return Py_ReturnFalse(); } py_loader_thread_release(); @@ -341,7 +304,7 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (ret != 0) { - result = handle == NULL ? py_loader_port_false() : py_loader_port_none(); + result = handle == NULL ? Py_ReturnFalse() : Py_ReturnNone(); } else { @@ -357,8 +320,8 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject if (wrapper == NULL) { - Py_XDECREF(result); - result = py_loader_port_none(); + Py_DecRef(result); + result = Py_ReturnNone(); } else { @@ -367,7 +330,7 @@ static PyObject *py_loader_port_load_from_package_impl(PyObject *self, PyObject } else { - result = py_loader_port_true(); + result = Py_ReturnTrue(); } } @@ -397,8 +360,8 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &tag, &buffer)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_load_from_memory('node', 'console.log(\"hello\")');"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_load_from_memory('node', 'console.log(\"hello\")');"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -407,8 +370,8 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) if (!PyUnicode_Check(tag)) #endif { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in first argument (a string indicating the tag of the loader must be used: 'node', 'rb', 'ts', 'cs', 'js', 'cob'...)"); + return Py_ReturnFalse(); } #if PY_MAJOR_VERSION == 2 @@ -417,8 +380,8 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) if (!PyUnicode_Check(buffer)) #endif { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in second argument (a string indicating the tag of the loader must be used: 'console.log(\"hello\")')"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in second argument (a string indicating the tag of the loader must be used: 'console.log(\"hello\")')"); + return Py_ReturnFalse(); } /* Convert tag from unicode into a string */ @@ -437,8 +400,8 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) if (tag_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid tag string conversion"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid tag string conversion"); + return Py_ReturnFalse(); } /* Convert buffer from unicode into a string */ @@ -457,8 +420,8 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) if (buffer_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid buffer string conversion"); - return py_loader_port_false(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid buffer string conversion"); + return Py_ReturnFalse(); } /* Execute the load from memory call */ @@ -471,11 +434,11 @@ static PyObject *py_loader_port_load_from_memory(PyObject *self, PyObject *args) if (ret != 0) { - return py_loader_port_false(); + return Py_ReturnFalse(); } } - return py_loader_port_true(); + return Py_ReturnTrue(); } static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) @@ -493,19 +456,12 @@ static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) /* Obtain Python loader implementation */ impl = loader_get_impl(py_loader_tag); - /* TODO: Remove this check when we implement this: https://github.com/metacall/core/issues/231 */ - if (impl == NULL) - { - PyErr_SetString(PyExc_ValueError, "Invalid Python loader instance, MetaCall Port must be used from MetaCall CLI"); - return py_loader_port_none(); - } - var_args_size = PyTuple_Size(var_args); if (var_args_size == 0) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall('function_name', 'asd', 123, [7, 4]);"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall('function_name', 'asd', 123, [7, 4]);"); + return Py_ReturnNone(); } name = PyTuple_GetItem(var_args, 0); @@ -525,8 +481,8 @@ static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) if (name_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid function name string conversion, first parameter must be a string"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid function name string conversion, first parameter must be a string"); + return Py_ReturnNone(); } /* Get variable arguments length */ @@ -539,8 +495,8 @@ static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) if (value_args == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid argument allocation"); - return py_loader_port_none(); + PyErr_SetString(PyExc_ValueErrorPtr(), "Invalid argument allocation"); + return Py_ReturnNone(); } /* Parse variable arguments */ @@ -571,7 +527,7 @@ static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) if (ret == NULL) { - result = py_loader_port_none(); + result = Py_ReturnNone(); goto clear; } @@ -583,7 +539,7 @@ static PyObject *py_loader_port_invoke(PyObject *self, PyObject *var_args) if (result == NULL) { - result = py_loader_port_none(); + result = Py_ReturnNone(); goto clear; } } @@ -623,19 +579,12 @@ static PyObject *py_loader_port_await(PyObject *self, PyObject *var_args) /* Obtain Python loader implementation */ impl = loader_get_impl(py_loader_tag); - /* TODO: Remove this check when we implement this: https://github.com/metacall/core/issues/231 */ - if (impl == NULL) - { - PyErr_SetString(PyExc_ValueError, "Invalid Python loader instance, MetaCall Port must be used from MetaCall CLI"); - return py_loader_port_none(); - } - var_args_size = PyTuple_Size(var_args); if (var_args_size == 0) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall('function_name', 'asd', 123, [7, 4]);"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall('function_name', 'asd', 123, [7, 4]);"); + return Py_ReturnNone(); } name = PyTuple_GetItem(var_args, 0); @@ -655,8 +604,8 @@ static PyObject *py_loader_port_await(PyObject *self, PyObject *var_args) if (name_str == NULL) { - PyErr_SetString(PyExc_TypeError, "Invalid function name string conversion, first parameter must be a string"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid function name string conversion, first parameter must be a string"); + return Py_ReturnNone(); } /* Get variable arguments length */ @@ -669,8 +618,8 @@ static PyObject *py_loader_port_await(PyObject *self, PyObject *var_args) if (value_args == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid argument allocation"); - return py_loader_port_none(); + PyErr_SetString(PyExc_ValueErrorPtr(), "Invalid argument allocation"); + return Py_ReturnNone(); } /* Parse variable arguments */ @@ -704,7 +653,7 @@ static PyObject *py_loader_port_await(PyObject *self, PyObject *var_args) if (ret == NULL) { - result = py_loader_port_none(); + result = Py_ReturnNone(); goto clear; } @@ -714,7 +663,7 @@ static PyObject *py_loader_port_await(PyObject *self, PyObject *var_args) if (result == NULL) { - result = py_loader_port_none(); + result = Py_ReturnNone(); goto clear; } } @@ -761,7 +710,7 @@ static PyObject *py_loader_port_inspect(PyObject *self, PyObject *args) result_str = (char *)empty; size = sizeof(empty); - PyErr_SetString(PyExc_ValueError, "Inspect returned an invalid size or string"); + PyErr_SetString(PyExc_ValueErrorPtr(), "Inspect returned an invalid size or string"); } #if PY_MAJOR_VERSION == 2 @@ -790,17 +739,17 @@ static PyObject *py_loader_port_value_create_ptr(PyObject *self, PyObject *args) /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &pointer)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_value_create_ptr(None); or metacall_value_create_ptr(previous_allocated_ptr);"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_value_create_ptr(None); or metacall_value_create_ptr(previous_allocated_ptr);"); + return Py_ReturnNone(); } - if (!PyCapsule_CheckExact(pointer) && pointer != Py_None) + if (!PyCapsule_CheckExact(pointer) && pointer != Py_NonePtr()) { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in first argument must be None or a PyCapsule (i.e a previously allocated pointer)"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in first argument must be None or a PyCapsule (i.e a previously allocated pointer)"); + return Py_ReturnNone(); } - if (pointer == Py_None) + if (pointer == Py_NonePtr()) { return py_loader_impl_capsule_new_null(); } @@ -837,22 +786,18 @@ static PyObject *py_loader_port_value_reference(PyObject *self, PyObject *args) /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &obj)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_value_reference(obj);"); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_value_reference(obj);"); goto error_none; } /* Obtain Python loader implementation */ impl = loader_get_impl(py_loader_tag); - /* TODO: When using the port outside MetaCall this is going to segfault for functions and similar - * structures that require py loader internal structure to be initialized. For those cases, we - * must implement this: https://github.com/metacall/core/issues/231 - */ v = py_loader_impl_capi_to_value(impl, obj, py_loader_impl_capi_to_value_type(impl, obj)); if (v == NULL) { - PyErr_SetString(PyExc_ValueError, "Failed to convert the Python object to MetaCall value."); + PyErr_SetString(PyExc_ValueErrorPtr(), "Failed to convert the Python object to MetaCall value."); goto error_none; } @@ -868,7 +813,7 @@ static PyObject *py_loader_port_value_reference(PyObject *self, PyObject *args) error_value: metacall_value_destroy(v); error_none: - return py_loader_port_none(); + return Py_ReturnNone(); } static PyObject *py_loader_port_value_dereference(PyObject *self, PyObject *args) @@ -885,15 +830,15 @@ static PyObject *py_loader_port_value_dereference(PyObject *self, PyObject *args /* Parse arguments */ if (!PyArg_ParseTuple(args, (char *)format, &capsule)) { - PyErr_SetString(PyExc_TypeError, "Invalid number of arguments, use it like: metacall_value_dereference(ptr);"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid number of arguments, use it like: metacall_value_dereference(ptr);"); + return Py_ReturnNone(); } /* Check if it is a valid reference */ if (!PyCapsule_CheckExact(capsule)) { - PyErr_SetString(PyExc_TypeError, "Invalid parameter type in first argument must be a PyCapsule (i.e a previously allocated pointer)"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid parameter type in first argument must be a PyCapsule (i.e a previously allocated pointer)"); + return Py_ReturnNone(); } /* Check if it is a valid MetaCall reference */ @@ -901,8 +846,8 @@ static PyObject *py_loader_port_value_dereference(PyObject *self, PyObject *args if (name != py_loader_capsule_reference_id) { - PyErr_SetString(PyExc_TypeError, "Invalid reference, argument must be a PyCapsule from MetaCall"); - return py_loader_port_none(); + PyErr_SetString(PyExc_TypeErrorPtr(), "Invalid reference, argument must be a PyCapsule from MetaCall"); + return Py_ReturnNone(); } /* Get the value */ @@ -910,27 +855,61 @@ static PyObject *py_loader_port_value_dereference(PyObject *self, PyObject *args if (v == NULL) { - return py_loader_port_none(); + return Py_ReturnNone(); } /* Obtain Python loader implementation */ impl = loader_get_impl(py_loader_tag); - /* TODO: When using the port outside MetaCall this is going to segfault for functions and similar - * structures that require py loader internal structure to be initialized. For those cases, we - * must implement this: https://github.com/metacall/core/issues/231 - */ result = py_loader_impl_value_to_capi(impl, value_type_id(v), v); if (result == NULL) { - PyErr_SetString(PyExc_ValueError, "Failed to convert the MetaCall value to Python object."); - return py_loader_port_none(); + PyErr_SetString(PyExc_ValueErrorPtr(), "Failed to convert the MetaCall value to Python object."); + return Py_ReturnNone(); } return result; } +static PyObject *py_loader_port_atexit(PyObject *self, PyObject *args) +{ + loader_impl impl = loader_get_impl(py_loader_tag); + + (void)self; + (void)args; + + if (impl != NULL) + { + if (py_loader_impl_destroy(impl) != 0) + { + PyErr_SetString(PyExc_RuntimeErrorPtr(), "Failed to destroy Python Loader on MetaCall."); + } + } + + 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." }, @@ -952,29 +931,40 @@ static PyMethodDef metacall_methods[] = { "Create a new value of type Pointer." }, { "metacall_value_dereference", py_loader_port_value_dereference, METH_VARARGS, "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 } }; -static struct PyModuleDef metacall_definition = { - PyModuleDef_HEAD_INIT, - "metacall", - "A library for providing inter-language foreign function interface calls.", - -1, - metacall_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PY_LOADER_PORT_NAME_FUNC(void) +int py_port_initialize(void) { - static PyObject *module = NULL; + static struct PyModuleDef metacall_definition = { + PyModuleDef_HEAD_INIT, + "py_port_impl_module", + "A library for providing inter-language foreign function interface calls.", + -1, + metacall_methods, + NULL, + NULL, + NULL, + NULL + }; + + PyObject *module = PyModule_Create(&metacall_definition); if (module == NULL) { - module = PyModule_Create(&metacall_definition); + return 1; + } + + PyObject *sys_modules = PyImport_GetModuleDict(); + + if (PyDict_SetItemString(sys_modules, metacall_definition.m_name, module) < 0) + { + return 1; } - return module; + return 0; } diff --git a/source/loaders/py_loader/source/py_loader_symbol_fallback.c b/source/loaders/py_loader/source/py_loader_symbol_fallback.c new file mode 100644 index 0000000000..1f5e55ff9e --- /dev/null +++ b/source/loaders/py_loader/source/py_loader_symbol_fallback.c @@ -0,0 +1,460 @@ +/* + * Loader Library by Parra Studios + * A plugin for loading python code at run-time into a process. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 + +#include + +/* Required for Windows due to DELAYLOAD not supporting delayed import of data symbols */ + +#if defined(_WIN32) && defined(_MSC_VER) +static PyTypeObject *PyBool_TypePtr = NULL; +static PyTypeObject *PyFloat_TypePtr = NULL; +static PyTypeObject *PyCapsule_TypePtr = NULL; +static PyTypeObject *PyFunction_TypePtr = NULL; +static PyTypeObject *PyCFunction_TypePtr = NULL; +static PyTypeObject *PyStaticMethod_TypePtr = NULL; +static PyTypeObject *PyDictProxy_TypePtr = NULL; +static PyTypeObject *PyDict_TypePtr = NULL; +static PyTypeObject *PyModule_TypePtr = NULL; +static PyTypeObject *PyType_TypePtr = NULL; +static PyObject *Py_NoneStructPtr = NULL; +static PyObject **PyExc_ExceptionStructPtr = NULL; +static PyObject **PyExc_FileNotFoundErrorStructPtr = NULL; +static PyObject **PyExc_TypeErrorStructPtr = NULL; +static PyObject **PyExc_ValueErrorStructPtr = NULL; +static PyObject **PyExc_RuntimeErrorStructPtr = NULL; +static PyObject *Py_FalseStructPtr = NULL; +static PyObject *Py_TrueStructPtr = NULL; +#endif + +int py_loader_symbol_fallback_initialize(dynlink py_library) +{ +#if defined(_WIN32) && defined(_MSC_VER) + dynlink_symbol_addr address; + + if (py_library == NULL) + { + return 1; + } + + /* PyBool_Type */ + if (dynlink_symbol(py_library, "PyBool_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyBool_TypePtr); + + /* PyFloat_Type */ + if (dynlink_symbol(py_library, "PyFloat_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyFloat_TypePtr); + + /* PyCapsule_Type */ + if (dynlink_symbol(py_library, "PyCapsule_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyCapsule_TypePtr); + + /* PyFunction_Type */ + if (dynlink_symbol(py_library, "PyFunction_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyFunction_TypePtr); + + /* PyCFunction_Type */ + if (dynlink_symbol(py_library, "PyCFunction_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyCFunction_TypePtr); + + /* PyStaticMethod_Type */ + if (dynlink_symbol(py_library, "PyStaticMethod_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyStaticMethod_TypePtr); + + /* PyDict_TypePtr */ + if (dynlink_symbol(py_library, "PyDict_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyDict_TypePtr); + + /* PyDictProxy_TypePtr */ + if (dynlink_symbol(py_library, "PyDictProxy_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyDictProxy_TypePtr); + + /* PyModule_Type */ + if (dynlink_symbol(py_library, "PyModule_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyModule_TypePtr); + + /* PyType_Type */ + if (dynlink_symbol(py_library, "PyType_Type", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyTypeObject *, PyType_TypePtr); + + /* Py_None */ + if (dynlink_symbol(py_library, "_Py_NoneStruct", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject *, Py_NoneStructPtr); + + /* PyExc_Exception */ + if (dynlink_symbol(py_library, "PyExc_Exception", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject **, PyExc_ExceptionStructPtr); + + /* PyExc_FileNotFoundError */ + if (dynlink_symbol(py_library, "PyExc_FileNotFoundError", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject **, PyExc_FileNotFoundErrorStructPtr); + + /* PyExc_TypeError */ + if (dynlink_symbol(py_library, "PyExc_TypeError", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject **, PyExc_TypeErrorStructPtr); + + /* PyExc_ValueError */ + if (dynlink_symbol(py_library, "PyExc_ValueError", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject **, PyExc_ValueErrorStructPtr); + + /* PyExc_RuntimeError */ + if (dynlink_symbol(py_library, "PyExc_RuntimeError", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject **, PyExc_RuntimeErrorStructPtr); + + /* Py_False */ + if (dynlink_symbol(py_library, "_Py_FalseStruct", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject *, Py_FalseStructPtr); + + /* Py_True */ + if (dynlink_symbol(py_library, "_Py_TrueStruct", &address) != 0) + { + return 1; + } + + dynlink_symbol_uncast_type(address, PyObject *, Py_TrueStructPtr); + + return 0; +#else + (void)py_library; + return 0; +#endif +} + +#if defined(_WIN32) && defined(_MSC_VER) +int PyBool_Check(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyBool_TypePtr); +} + +int PyFloat_Check(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyFloat_TypePtr); +} + +int PyCapsule_CheckExact(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyCapsule_TypePtr); +} + +int PyFunction_Check(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyFunction_TypePtr); +} + +int PyCFunction_Check(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyCFunction_TypePtr); +} + +int PyModule_Check(const PyObject *ob) +{ + return Py_IS_TYPE(ob, PyModule_TypePtr); +} +#endif + +PyTypeObject *PyCFunctionTypePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return PyCFunction_TypePtr; +#else + return &PyCFunction_Type; +#endif +} + +PyTypeObject *PyStaticMethodTypePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return PyStaticMethod_TypePtr; +#else + return &PyStaticMethod_Type; +#endif +} + +PyTypeObject *PyDictTypePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return PyDict_TypePtr; +#else + return &PyDict_Type; +#endif +} + +PyTypeObject *PyDictProxyTypePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return PyDictProxy_TypePtr; +#else + return &PyDictProxy_Type; +#endif +} + +PyTypeObject *PyTypeTypePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return PyType_TypePtr; +#else + return &PyType_Type; +#endif +} + +PyObject *Py_NonePtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return Py_NoneStructPtr; +#else + return Py_None; +#endif +} + +PyObject *PyExc_ExceptionPtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return *PyExc_ExceptionStructPtr; +#else + return PyExc_Exception; +#endif +} + +PyObject *PyExc_FileNotFoundErrorPtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return *PyExc_FileNotFoundErrorStructPtr; +#else + return PyExc_FileNotFoundError; +#endif +} + +PyObject *PyExc_TypeErrorPtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return *PyExc_TypeErrorStructPtr; +#else + return PyExc_TypeError; +#endif +} + +PyObject *PyExc_ValueErrorPtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return *PyExc_ValueErrorStructPtr; +#else + return PyExc_ValueError; +#endif +} + +PyObject *PyExc_RuntimeErrorPtr(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + return *PyExc_RuntimeErrorStructPtr; +#else + return PyExc_RuntimeError; +#endif +} + +PyObject *Py_ReturnNone(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + Py_IncRef(Py_NoneStructPtr); + return Py_NoneStructPtr; +#else + Py_RETURN_NONE; +#endif +} + +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wstrict-aliasing" +#elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#elif defined(_MSC_VER) + #pragma warning(push) +// TODO +#endif + +PyObject *Py_ReturnFalse(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + Py_IncRef(Py_FalseStructPtr); + return Py_FalseStructPtr; +#else + Py_RETURN_FALSE; +#endif +} + +PyObject *Py_ReturnTrue(void) +{ +#if defined(_WIN32) && defined(_MSC_VER) + Py_IncRef(Py_TrueStructPtr); + return Py_TrueStructPtr; +#else + Py_RETURN_TRUE; +#endif +} + +#if defined(__clang__) + #pragma clang diagnostic pop +#elif defined(__GNUC__) + #pragma GCC diagnostic pop +#elif defined(_MSC_VER) + #pragma warning(pop) +#endif + +/* Required on GNU for when linking to Python in debug mode and loading with Python.elf in release mode */ +#if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) + #if defined(__clang__) || defined(__GNUC__) + +__attribute__((weak)) void _Py_DECREF_DecRefTotal(void) +{ +} +__attribute__((weak)) void _Py_INCREF_IncRefTotal(void) {} +__attribute__((weak)) Py_ssize_t _Py_RefTotal; + + /* When Python has been compiled with tracing reference counting, + * provide fallback symbols for allowing it to compile properly */ + #ifdef Py_TRACE_REFS + + #include + + #undef PyModule_Create2 + #undef PyModule_FromDefAndSpec2 + +static dynlink_symbol_addr py_loader_symbol(const char *name) +{ + dynlink proc = dynlink_load_self(DYNLINK_FLAGS_BIND_NOW | DYNLINK_FLAGS_BIND_GLOBAL); + dynlink_symbol_addr addr = NULL; + + if (proc == NULL) + { + return NULL; + } + + dynlink_symbol(proc, name, &addr); + + dynlink_unload(proc); + + return addr; +} + +__attribute__((weak)) PyObject *PyModule_Create2(struct PyModuleDef *module, int module_api_version) +{ + static PyObject *(*py_module_create2)(struct PyModuleDef *, int) = NULL; + + if (py_module_create2 == NULL) + { + py_module_create2 = (PyObject * (*)(struct PyModuleDef *, int)) py_loader_symbol("PyModule_Create2TraceRefs"); + } + + if (py_module_create2 == NULL) + { + return NULL; + } + + return py_module_create2(module, module_api_version); +} +__attribute__((weak)) PyObject *PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version) +{ + static PyObject *(*py_module_from_def_and_spec2)(struct PyModuleDef *, PyObject *, int) = NULL; + + if (py_module_from_def_and_spec2 == NULL) + { + py_module_from_def_and_spec2 = (PyObject * (*)(struct PyModuleDef *, PyObject *, int)) py_loader_symbol("PyModule_FromDefAndSpec2TraceRefs"); + } + + if (py_module_from_def_and_spec2 == NULL) + { + return NULL; + } + + return py_module_from_def_and_spec2(def, spec, module_api_version); +} + + #endif + #endif +#endif diff --git a/source/loaders/py_loader/source/py_loader_threading.cpp b/source/loaders/py_loader/source/py_loader_threading.cpp index 75f11f230a..64a0ab7fb0 100644 --- a/source/loaders/py_loader/source/py_loader_threading.cpp +++ b/source/loaders/py_loader/source/py_loader_threading.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,7 @@ #include -#include - -#include +#include struct py_thread_state { @@ -32,7 +30,7 @@ struct py_thread_state PyGILState_STATE gstate; py_thread_state() : - ref_count(0) {} + ref_count(0), gstate(PyGILState_UNLOCKED) {} void ensure() { @@ -63,10 +61,32 @@ static uint64_t main_thread_id = 0; static uint64_t main_thread_ref_count = 0; thread_local py_thread_state current_thread_state; thread_local uint64_t current_thread_id = thread_id_get_current(); +static std::vector delayed_destructor; -void py_loader_thread_initialize() +int py_loader_thread_initialize(const int host) { main_thread_id = thread_id_get_current(); + + if (host == 1) + { + const int gil_status = PyGILState_Check(); + + PyGILState_STATE gstate = PyGILState_Ensure(); + main_thread_state = PyThreadState_Get(); + PyGILState_Release(gstate); + + if (gil_status == 0) + { + py_loader_thread_acquire(); + return 1; + } + else + { + main_thread_ref_count++; + } + } + + return 0; } int py_loader_thread_is_main() @@ -115,3 +135,29 @@ void py_loader_thread_release() current_thread_state.release(); } } + +void py_loader_thread_delayed_destroy(PyObject *obj) +{ + if (main_thread_id == current_thread_id) + { + py_loader_thread_acquire(); + Py_DecRef(obj); + py_loader_thread_release(); + } + else + { + delayed_destructor.push_back(obj); + } +} + +void py_loader_thread_destroy(void) +{ + py_loader_thread_acquire(); + + for (auto obj : delayed_destructor) + { + Py_DecRef(obj); + } + + py_loader_thread_release(); +} diff --git a/source/loaders/rb_loader/CMakeLists.txt b/source/loaders/rb_loader/CMakeLists.txt index 787fb3a17f..3e6d2cbdb7 100644 --- a/source/loaders/rb_loader/CMakeLists.txt +++ b/source/loaders/rb_loader/CMakeLists.txt @@ -14,14 +14,15 @@ if(NOT Ruby_FOUND) return() endif() -# Copy Ruby DLL into project output directory -# TODO: https://cmake.org/cmake/help/latest/command/file.html#get-runtime-dependencies -# TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da -if(WIN32 AND Ruby_LIBRARY_NAME) - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_OUTPUT_DIR}) - file(COPY "${Ruby_LIBRARY_NAME}" DESTINATION ${PROJECT_OUTPUT_DIR}) +# TODO: Search Ruby_LIBRARY_NAME_PATH like in Python? +if(Ruby_LIBRARY_NAME) + set(Ruby_LIBRARY_NAME_PATH "${Ruby_LIBRARY_NAME}") +else() + set(Ruby_LIBRARY_NAME_PATH "${Ruby_LIBRARY}") endif() +get_filename_component(Ruby_LIBRARY_NAME "${Ruby_LIBRARY_NAME_PATH}" NAME) + # # Plugin name and options # @@ -58,14 +59,17 @@ set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(headers ${include_path}/rb_loader.h + ${include_path}/rb_loader_include.h ${include_path}/rb_loader_impl.h ${include_path}/rb_loader_impl_parser.h + ${include_path}/rb_loader_port.h ) set(sources ${source_path}/rb_loader.c ${source_path}/rb_loader_impl.c ${source_path}/rb_loader_impl_parser.c + ${source_path}/rb_loader_port.c ) # Group source files @@ -139,7 +143,9 @@ target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library - ${Ruby_LIBRARY} # Ruby library + # Delay load for MSVC + $<$:${Ruby_LIBRARY}> # Ruby library + $<$:delayimp> PUBLIC ${DEFAULT_LIBRARIES} @@ -186,8 +192,10 @@ endif() # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE + $<$,$>:-Wl,-undefined,dynamic_lookup> + $<$:/DELAYLOAD:${Ruby_LIBRARY_NAME_PATH}> PUBLIC ${DEFAULT_LINKER_OPTIONS} @@ -210,10 +218,50 @@ install(TARGETS ${target} # Runtime (pack Ruby DLL in windows) # TODO: https://cmake.org/cmake/help/latest/command/file.html#get-runtime-dependencies # TODO: https://gist.github.com/micahsnyder/5d98ac8548b429309ec5a35bca9366da -if(WIN32 AND Ruby_LIBRARY_NAME) +set(Ruby_LIBRARY_DEVELOPMENT "${Ruby_LIBRARY_NAME_PATH}") + +if(Ruby_LIBRARY_NAME_PATH AND WIN32) install(FILES - "${Ruby_LIBRARY_NAME}" + "${Ruby_LIBRARY_NAME_PATH}" DESTINATION ${INSTALL_LIB} COMPONENT runtime ) + set(Ruby_LIBRARY_INSTALL "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/${Ruby_LIBRARY_NAME}") +else() + set(Ruby_LIBRARY_INSTALL "${Ruby_LIBRARY_NAME_PATH}") endif() + +# Define search paths +set(Ruby_LIBRARY_SEARCH_PATHS_DEVELOPMENT "${Ruby_LIBRARY_SEARCH_PATHS}") + +if(Ruby_LIBRARY_SEARCH_PATHS AND WIN32) + set(Ruby_LIBRARY_SEARCH_PATHS_INSTALL "") + + foreach(SEARCH_PATH IN LISTS Ruby_LIBRARY_SEARCH_PATHS) + install(DIRECTORY + "${SEARCH_PATH}" + DESTINATION ${INSTALL_LIB} + COMPONENT runtime + ) + + get_filename_component(SEARCH_PATH_FOLDER_NAME "${SEARCH_PATH}" NAME) + + list(APPEND Ruby_LIBRARY_SEARCH_PATHS_INSTALL "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIB}/${SEARCH_PATH_FOLDER_NAME}") + endforeach() +endif() + +# +# Configuration +# + +# Development +loader_configuration_begin(rb_loader) +loader_configuration_paths("${Ruby_LIBRARY_SEARCH_PATHS_DEVELOPMENT}") +loader_configuration_deps(ruby "${Ruby_LIBRARY_DEVELOPMENT}") +loader_configuartion_end_development() + +# Install +loader_configuration_begin(rb_loader) +loader_configuration_paths("${Ruby_LIBRARY_SEARCH_PATHS_INSTALL}") +loader_configuration_deps(ruby "${Ruby_LIBRARY_INSTALL}") +loader_configuartion_end_install() diff --git a/source/loaders/rb_loader/include/rb_loader/rb_loader.h b/source/loaders/rb_loader/include/rb_loader/rb_loader.h index 49b53024c0..52e07d650e 100644 --- a/source/loaders/rb_loader/include/rb_loader/rb_loader.h +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RB_LOADER_API loader_impl_interface rb_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rb_loader_impl_interface_singleton); - RB_LOADER_API const char *rb_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rb_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rb_loader/include/rb_loader/rb_loader_impl.h b/source/loaders/rb_loader/include/rb_loader/rb_loader_impl.h index 39b2744d0e..f5a6e3b85e 100644 --- a/source/loaders/rb_loader/include/rb_loader/rb_loader_impl.h +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,10 @@ #include +#include + +#include + #ifdef __cplusplus extern "C" { #endif @@ -47,6 +51,10 @@ RB_LOADER_API int rb_loader_impl_discover(loader_impl impl, loader_handle handle RB_LOADER_API int rb_loader_impl_destroy(loader_impl impl); +RB_LOADER_NO_EXPORT const char *rb_type_deserialize(loader_impl impl, VALUE v, value *result); + +RB_LOADER_NO_EXPORT VALUE rb_type_serialize(value v); + #ifdef __cplusplus } #endif diff --git a/source/loaders/rb_loader/include/rb_loader/rb_loader_impl_parser.h b/source/loaders/rb_loader/include/rb_loader/rb_loader_impl_parser.h index 77a232b2a7..8c739f706a 100644 --- a/source/loaders/rb_loader/include/rb_loader/rb_loader_impl_parser.h +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader_impl_parser.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ #ifndef RB_LOADER_IMPL_PARSER_H #define RB_LOADER_IMPL_PARSER_H 1 +#include + #include #ifdef __cplusplus @@ -48,11 +50,11 @@ typedef struct rb_function_parser_type } * rb_function_parser; -int rb_loader_impl_key_parse(const char *source, set function_map); +RB_LOADER_NO_EXPORT int rb_loader_impl_key_parse(const char *source, set function_map); -void rb_loader_impl_key_print(set function_map); +RB_LOADER_NO_EXPORT void rb_loader_impl_key_print(set function_map); -void rb_loader_impl_key_clear(set function_map); +RB_LOADER_NO_EXPORT void rb_loader_impl_key_clear(set function_map); #ifdef __cplusplus } diff --git a/source/loaders/rb_loader/include/rb_loader/rb_loader_include.h b/source/loaders/rb_loader/include/rb_loader/rb_loader_include.h new file mode 100644 index 0000000000..a8874b1b2c --- /dev/null +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader_include.h @@ -0,0 +1,82 @@ +/* + * 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 + * + * 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 RB_LOADER_INCLUDE_H +#define RB_LOADER_INCLUDE_H 1 + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(_MSC_VER) && defined(boolean) + #undef boolean +#endif + +/* Disable warnings from Ruby */ +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunused-parameter" +#elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wredundant-decls" + #pragma GCC diagnostic ignored "-Wpedantic" + #pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#include + +/* Disable warnings from Ruby */ +#if defined(__clang__) + #pragma clang diagnostic pop +#elif defined(__GNUC__) + #pragma GCC diagnostic pop +#endif + +/* Backward compatible macros for Ruby < 2.7 */ +#ifndef RB_PASS_KEYWORDS + #define rb_funcallv_kw(o, m, c, v, kw) rb_funcallv(o, m, c, v) + #define rb_funcallv_public_kw(o, m, c, v, kw) rb_funcallv_public(o, m, c, v) + #define rb_funcall_passing_block_kw(o, m, c, v, kw) rb_funcall_passing_block(o, m, c, v) + #define rb_funcall_with_block_kw(o, m, c, v, b, kw) rb_funcall_with_block(o, m, c, v, b) + #define rb_scan_args_kw(kw, c, v, s, ...) rb_scan_args(c, v, s, __VA_ARGS__) + #define rb_call_super_kw(c, v, kw) rb_call_super(c, v) + #define rb_yield_values_kw(c, v, kw) rb_yield_values2(c, v) + #define rb_yield_splat_kw(a, kw) rb_yield_splat(a) + #define rb_block_call_kw(o, m, c, v, f, p, kw) rb_block_call(o, m, c, v, f, p) + #define rb_fiber_resume_kw(o, c, v, kw) rb_fiber_resume(o, c, v) + #define rb_fiber_yield_kw(c, v, kw) rb_fiber_yield(c, v) + #define rb_enumeratorize_with_size_kw(o, m, c, v, f, kw) rb_enumeratorize_with_size(o, m, c, v, f) + #define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ + rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \ + (argc), (argv), (size_fn)) + #define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ + do \ + { \ + if (!rb_block_given_p()) \ + return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \ + } while (0) + #define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0) + #define rb_check_funcall_kw(o, m, c, v, kw) rb_check_funcall(o, m, c, v) + #define rb_obj_call_init_kw(o, c, v, kw) rb_obj_call_init(o, c, v) + #define rb_class_new_instance_kw(c, v, k, kw) rb_class_new_instance(c, v, k) + #define rb_proc_call_kw(p, a, kw) rb_proc_call(p, a) + #define rb_proc_call_with_block_kw(p, c, v, b, kw) rb_proc_call_with_block(p, c, v, b) + #define rb_method_call_kw(c, v, m, kw) rb_method_call(c, v, m) + #define rb_method_call_with_block_kw(c, v, m, b, kw) rb_method_call_with_block(c, v, m, b) + #define rb_eval_cmd_kwd(c, a, kw) rb_eval_cmd(c, a, 0) +#endif + +#endif /* RB_LOADER_INCLUDE_H */ diff --git a/source/ports/rb_port/include/rb_port/rb_port.h b/source/loaders/rb_loader/include/rb_loader/rb_loader_port.h similarity index 51% rename from source/ports/rb_port/include/rb_port/rb_port.h rename to source/loaders/rb_loader/include/rb_loader/rb_loader_port.h index d2682f4b82..0ccc7a4977 100644 --- a/source/ports/rb_port/include/rb_port/rb_port.h +++ b/source/loaders/rb_loader/include/rb_loader/rb_loader_port.h @@ -1,8 +1,8 @@ /* - * MetaCall SWIG Wrapper by Parra Studios - * A complete infrastructure for supporting multiple language bindings in MetaCall. + * Loader Library by Parra Studios + * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,21 @@ * */ -#ifndef METACALL_SWIG_WRAPPER_RB_PORT_H -#define METACALL_SWIG_WRAPPER_RB_PORT_H 1 +#ifndef RB_LOADER_PORT_H +#define RB_LOADER_PORT_H 1 -/* TODO: Review https://github.com/SketchUp/testup-2/blob/e32a68c5c02e2cbc3a924f40d4987faa05dbcc89/ruby-c-extension/sketchup-taskbarlist/TaskbarProgress/src/RubyUtils/RubyLib.h */ -/* TODO: Unify rb_port with rb_loader */ +#include -/* ... */ +#include -#endif /* METACALL_SWIG_WRAPPER_RB_PORT_H */ +#ifdef __cplusplus +extern "C" { +#endif + +RB_LOADER_NO_EXPORT int rb_loader_port_initialize(loader_impl impl); + +#ifdef __cplusplus +} +#endif + +#endif /* RB_LOADER_PORT_H */ diff --git a/source/loaders/rb_loader/source/rb_loader.c b/source/loaders/rb_loader/source/rb_loader.c index 7bea40663c..8603917e35 100644 --- a/source/loaders/rb_loader/source/rb_loader.c +++ b/source/loaders/rb_loader/source/rb_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *rb_loader_print_info(void) { static const char rb_loader_info[] = "Ruby Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef RB_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/rb_loader/source/rb_loader_impl.c b/source/loaders/rb_loader/source/rb_loader_impl.c index 6cb99ae050..9d0e43afbb 100644 --- a/source/loaders/rb_loader/source/rb_loader_impl.c +++ b/source/loaders/rb_loader/source/rb_loader_impl.c @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A plugin for loading ruby code at run-time into a process. * @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -25,68 +26,9 @@ #include -#include - #include #include -#if (defined(_WIN32) || defined(_WIN64)) && !defined(_MSC_VER) && defined(boolean) - #undef boolean -#endif - -/* Disable warnings from Ruby */ -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wunused-parameter" -#elif defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wredundant-decls" - #pragma GCC diagnostic ignored "-Wpedantic" -#endif - -#include - -/* Disable warnings from Ruby */ -#if defined(__clang__) - #pragma clang diagnostic pop -#elif defined(__GNUC__) - #pragma GCC diagnostic pop -#endif - -/* Backward compatible macros for Ruby < 2.7 */ -#ifndef RB_PASS_KEYWORDS - #define rb_funcallv_kw(o, m, c, v, kw) rb_funcallv(o, m, c, v) - #define rb_funcallv_public_kw(o, m, c, v, kw) rb_funcallv_public(o, m, c, v) - #define rb_funcall_passing_block_kw(o, m, c, v, kw) rb_funcall_passing_block(o, m, c, v) - #define rb_funcall_with_block_kw(o, m, c, v, b, kw) rb_funcall_with_block(o, m, c, v, b) - #define rb_scan_args_kw(kw, c, v, s, ...) rb_scan_args(c, v, s, __VA_ARGS__) - #define rb_call_super_kw(c, v, kw) rb_call_super(c, v) - #define rb_yield_values_kw(c, v, kw) rb_yield_values2(c, v) - #define rb_yield_splat_kw(a, kw) rb_yield_splat(a) - #define rb_block_call_kw(o, m, c, v, f, p, kw) rb_block_call(o, m, c, v, f, p) - #define rb_fiber_resume_kw(o, c, v, kw) rb_fiber_resume(o, c, v) - #define rb_fiber_yield_kw(c, v, kw) rb_fiber_yield(c, v) - #define rb_enumeratorize_with_size_kw(o, m, c, v, f, kw) rb_enumeratorize_with_size(o, m, c, v, f) - #define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ - rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \ - (argc), (argv), (size_fn)) - #define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ - do \ - { \ - if (!rb_block_given_p()) \ - return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \ - } while (0) - #define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0) - #define rb_check_funcall_kw(o, m, c, v, kw) rb_check_funcall(o, m, c, v) - #define rb_obj_call_init_kw(o, c, v, kw) rb_obj_call_init(o, c, v) - #define rb_class_new_instance_kw(c, v, k, kw) rb_class_new_instance(c, v, k) - #define rb_proc_call_kw(p, a, kw) rb_proc_call(p, a) - #define rb_proc_call_with_block_kw(p, c, v, b, kw) rb_proc_call_with_block(p, c, v, b) - #define rb_method_call_kw(c, v, m, kw) rb_method_call(c, v, m) - #define rb_method_call_with_block_kw(c, v, m, b, kw) rb_method_call_with_block(c, v, m, b) - #define rb_eval_cmd_kwd(c, a, kw) rb_eval_cmd(c, a, 0) -#endif - #define LOADER_IMPL_RB_FUNCTION_ARGS_SIZE 0x10 #define LOADER_IMPL_RB_PROTECT_ARGS_SIZE 0x10 @@ -147,10 +89,21 @@ 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)); +/* Implements executing the file as main instead of a module */ +static int rb_loader_impl_run_main = 1; +static char *rb_loader_impl_main_module = NULL; + int function_rb_interface_create(function func, function_impl impl) { signature s = function_signature(func); @@ -984,6 +937,8 @@ loader_impl_data rb_loader_impl_initialize(loader_impl impl, configuration confi NULL }; + const int host = loader_impl_get_option_host(impl); + /* Initialize Ruby */ char **argv = metacall_argv(); int argc = metacall_argc(); @@ -992,51 +947,83 @@ loader_impl_data rb_loader_impl_initialize(loader_impl impl, configuration confi (void)config; ruby_sysinit(&argc, &argv); + + if (argv != NULL && argc > 1) + { + rb_loader_impl_main_module = argv[1]; + + /* If we are running on host, this means the main is already executed by the host, so we can skip it, + * otherwise if we are not in host and we run it for the first time, we can prepare the loader + * for running the file as script instead of like a module + */ + if (host == 0) + { + rb_loader_impl_run_main = 0; + } + } + + if (host == 0) { RUBY_INIT_STACK; 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(); */ - if (rb_loader_impl_initialize_types(impl) != 0) - { - ruby_cleanup(0); + ruby_options(argc, argv); + } - return NULL; - } + if (rb_loader_impl_initialize_types(impl) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby loader failed to initialize the types"); + goto error_initialize; + } #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) - if (rb_gv_set("$VERBOSE", Qtrue) != Qtrue) - { - ruby_cleanup(0); - - return NULL; - } + if (rb_gv_set("$VERBOSE", Qtrue) != Qtrue) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby loader failed to initialize the $VERBOSE variable"); + goto error_initialize; + } #endif - /* Gem add home folder if any */ - /* - { - const char * gem_home_env = getenv("GEM_HOME"); + /* Gem add home folder if any */ + /* + { + const char * gem_home_env = getenv("GEM_HOME"); - if (gem_home_env != NULL) + if (gem_home_env != NULL) + { + if (rb_loader_impl_execution_path(impl, gem_home_env) != 0) { - if (rb_loader_impl_execution_path(impl, gem_home_env) != 0) - { - log_write("metacall", LOG_LEVEL_WARNING, "Ruby GEM_HOME could not be added to execution path list"); - } + log_write("metacall", LOG_LEVEL_WARNING, "Ruby GEM_HOME could not be added to execution path list"); } } - */ + } + */ - log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader initialized correctly"); + if (rb_loader_port_initialize(impl) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby loader failed to initialize the port"); + goto error_initialize; } + log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader initialized correctly"); + /* Register initialization */ loader_initialization_register(impl); return (loader_impl_data)&rb_loader_impl_unused; + +error_initialize: + if (host == 0) + { + ruby_cleanup(0); + } + return NULL; } int rb_loader_impl_execution_path(loader_impl impl, const loader_path path) @@ -1116,47 +1103,93 @@ VALUE rb_loader_impl_module_eval_protect(VALUE args) return rb_mod_module_eval(protect->argc, protect->argv, protect->module); } +static void rb_loader_impl_print_exception(void) +{ + VALUE exception = rb_gv_get("$!"); + + if (RTEST(exception)) + { + VALUE inspect, backtrace; + + inspect = rb_inspect(exception); + + rb_io_puts(1, &inspect, rb_stderr); + + backtrace = rb_funcallv(exception, rb_intern("backtrace"), 0, NULL); + + rb_io_puts(1, &backtrace, rb_stderr); + } + else + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby module backtrace not available"); + } +} + int rb_loader_impl_module_eval(VALUE module, VALUE module_data, VALUE *result) { - VALUE argv[1]; struct loader_impl_rb_module_eval_protect_type protect; int state; - argv[0] = module_data; - protect.argc = 1; - protect.argv = argv; + protect.argv = &module_data; protect.module = module; *result = rb_protect(rb_loader_impl_module_eval_protect, (VALUE)&protect, &state); if (state != 0) { - VALUE exception; - log_write("metacall", LOG_LEVEL_ERROR, "Ruby module evaluation failed"); + rb_loader_impl_print_exception(); + } - exception = rb_gv_get("$!"); + return state; +} - if (RTEST(exception)) - { - VALUE inspect, backtrace; +loader_impl_rb_module rb_loader_impl_create_module(VALUE name_capitalized, VALUE module, VALUE module_data, VALUE result) +{ + loader_impl_rb_module rb_module = malloc(sizeof(struct loader_impl_rb_module_type)); - inspect = rb_inspect(exception); + if (rb_module == NULL) + { + return NULL; + } - rb_io_puts(1, &inspect, rb_stderr); + if (result != Qnil) + { + rb_module->empty = 1; + rb_module->id = rb_to_id(name_capitalized); + rb_module->module = module; + rb_module->instance = rb_funcall(rb_cClass, rb_intern("new"), 1, rb_cObject); - backtrace = rb_funcallv(exception, rb_intern("backtrace"), 0, NULL); + rb_extend_object(rb_module->instance, rb_module->module); - rb_io_puts(1, &backtrace, rb_stderr); - } - else + rb_include_module(rb_module->instance, rb_module->module); + + rb_module->function_map = set_create(&hash_callback_str, &comparable_callback_str); + + if (!(rb_module->function_map != NULL && rb_loader_impl_key_parse(RSTRING_PTR(module_data), rb_module->function_map) == 0)) { - log_write("metacall", LOG_LEVEL_ERROR, "Ruby module backtrace not available"); + rb_loader_impl_key_clear(rb_module->function_map); + + free(rb_module); + + return NULL; } + + log_write("metacall", LOG_LEVEL_DEBUG, "Ruby module %s loaded", StringValuePtr(name_capitalized)); + + rb_loader_impl_key_print(rb_module->function_map); + } + else + { + rb_module->empty = 0; + rb_module->id = (ID)NULL; + rb_module->module = Qnil; + rb_module->instance = Qnil; + rb_module->function_map = NULL; } - return state; + return rb_module; } loader_impl_rb_module rb_loader_impl_load_from_file_module(loader_impl impl, const loader_path path, const loader_name name) @@ -1177,47 +1210,7 @@ loader_impl_rb_module rb_loader_impl_load_from_file_module(loader_impl impl, con if (rb_loader_impl_module_eval(module, module_data, &result) == 0) { - loader_impl_rb_module rb_module = malloc(sizeof(struct loader_impl_rb_module_type)); - - if (rb_module != NULL) - { - if (result != Qnil) - { - rb_module->empty = 1; - rb_module->id = rb_to_id(name_capitalized); - rb_module->module = module; - rb_module->instance = rb_funcall(rb_cClass, rb_intern("new"), 1, rb_cObject); - - rb_extend_object(rb_module->instance, rb_module->module); - - rb_include_module(rb_module->instance, rb_module->module); - - rb_module->function_map = set_create(&hash_callback_str, &comparable_callback_str); - - if (!(rb_module->function_map != NULL && rb_loader_impl_key_parse(RSTRING_PTR(module_data), rb_module->function_map) == 0)) - { - rb_loader_impl_key_clear(rb_module->function_map); - - free(rb_module); - - return NULL; - } - - log_write("metacall", LOG_LEVEL_DEBUG, "Ruby module %s loaded", path); - - rb_loader_impl_key_print(rb_module->function_map); - } - else - { - rb_module->empty = 0; - rb_module->id = (ID)NULL; - rb_module->module = Qnil; - rb_module->instance = Qnil; - rb_module->function_map = NULL; - } - - return rb_module; - } + return rb_loader_impl_create_module(name_capitalized, module, module_data, result); } } } @@ -1229,12 +1222,9 @@ loader_handle rb_loader_impl_load_from_file(loader_impl impl, const loader_path { loader_impl_rb_handle handle = malloc(sizeof(struct loader_impl_rb_handle_type)); - size_t iterator; - if (handle == NULL) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid ruby handle allocation"); - return NULL; } @@ -1243,45 +1233,170 @@ loader_handle rb_loader_impl_load_from_file(loader_impl impl, const loader_path if (handle->modules == NULL) { log_write("metacall", LOG_LEVEL_ERROR, "Invalid ruby modules vector allocation"); - - free(handle); - - return NULL; + goto vector_error; } - for (iterator = 0; iterator < size; ++iterator) + /* If we loaded one script and this script is the same as the one we passed to argv, + then we should set up this as a main script, only if only we set up the argv in MetaCall. + This should run only once, the first time after the initialization */ + if (rb_loader_impl_run_main == 0 && size == 1 && strcmp(paths[0], rb_loader_impl_main_module) == 0) { - static const char extension[] = "rb"; + VALUE module_data, result, module_name, module; + int state; loader_impl_rb_module rb_module; - loader_name module_name; - (void)portability_path_get_module_name(paths[iterator], strnlen(paths[iterator], LOADER_PATH_SIZE) + 1, extension, sizeof(extension), module_name, LOADER_NAME_SIZE); + rb_loader_impl_run_main = 1; + + module_data = rb_loader_impl_load_data(impl, paths[0]); + + if (module_data == Qnil) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby module not found: %s", paths[0]); + goto load_error; + } + + /* Define module name */ + { + loader_path name; + size_t size = portability_path_get_name(paths[0], strnlen(paths[0], LOADER_PATH_SIZE), name, LOADER_PATH_SIZE); + module_name = rb_str_new(name, size - 1); + module_name = rb_funcallv(module_name, rb_intern("capitalize"), 0, NULL); + } + + /* Define module that wraps the code */ + { +#define rb_str_new_static_size(str) rb_str_new_static(str, sizeof(str) - 1) + + 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\n")); + wrapped_code = rb_str_plus(wrapped_code, rb_str_new_static_size("AtExitInterceptor.run_all\n")); + +#undef rb_str_new_static_size + + module_data = wrapped_code; + } + + result = rb_eval_string_protect(StringValuePtr(module_data), &state); + + if (state != 0) + { + 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); - rb_module = rb_loader_impl_load_from_file_module(impl, paths[iterator], module_name); + 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 */ + module = rb_const_get(rb_cObject, rb_intern_str(module_name)); + + if (module == Qnil) + { + log_write("metacall", LOG_LEVEL_ERROR, "Ruby invalid module generation: %s", paths[0]); + goto load_error; + } + + rb_module = rb_loader_impl_create_module(module_name, module, module_data, result); if (rb_module == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid ruby module loading %s", paths[iterator]); + log_write("metacall", LOG_LEVEL_ERROR, "Invalid ruby module loading %s", paths[0]); } else { vector_push_back(handle->modules, &rb_module); } } - - // Do not load the handle in case there isn't modules - if (vector_size(handle->modules) == 0) + else { - log_write("metacall", LOG_LEVEL_ERROR, "No module could be loaded"); + size_t iterator; - vector_destroy(handle->modules); + for (iterator = 0; iterator < size; ++iterator) + { + static const char extension[] = "rb"; + loader_impl_rb_module rb_module; + loader_name module_name; - free(handle); + (void)portability_path_get_module_name(paths[iterator], strnlen(paths[iterator], LOADER_PATH_SIZE) + 1, extension, sizeof(extension), module_name, LOADER_NAME_SIZE); - return NULL; + rb_module = rb_loader_impl_load_from_file_module(impl, paths[iterator], module_name); + + if (rb_module == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid ruby module loading %s", paths[iterator]); + } + else + { + vector_push_back(handle->modules, &rb_module); + } + } + } + + /* Do not load the handle in case there isn't modules */ + if (vector_size(handle->modules) == 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "No module could be loaded"); + goto load_error; } return (loader_handle)handle; + +load_error: + vector_destroy(handle->modules); +vector_error: + free(handle); + return NULL; } loader_impl_rb_module rb_loader_impl_load_from_memory_module(loader_impl impl, const loader_name name, const char *buffer, size_t size) @@ -1305,47 +1420,7 @@ loader_impl_rb_module rb_loader_impl_load_from_memory_module(loader_impl impl, c if (rb_loader_impl_module_eval(module, module_data, &result) == 0) { - loader_impl_rb_module rb_module = malloc(sizeof(struct loader_impl_rb_module_type)); - - if (rb_module != NULL) - { - if (result != Qnil) - { - rb_module->empty = 1; - rb_module->id = rb_to_id(name_capitalized); - rb_module->module = module; - rb_module->instance = rb_funcall(rb_cClass, rb_intern("new"), 1, rb_cObject); - - rb_extend_object(rb_module->instance, rb_module->module); - - rb_include_module(rb_module->instance, rb_module->module); - - rb_module->function_map = set_create(&hash_callback_str, &comparable_callback_str); - - if (!(rb_module->function_map != NULL && rb_loader_impl_key_parse(RSTRING_PTR(module_data), rb_module->function_map) == 0)) - { - set_destroy(rb_module->function_map); - - free(rb_module); - - return NULL; - } - - log_write("metacall", LOG_LEVEL_DEBUG, "Ruby module %s loaded", name); - - rb_loader_impl_key_print(rb_module->function_map); - } - else - { - rb_module->empty = 0; - rb_module->id = (ID)NULL; - rb_module->module = Qnil; - rb_module->instance = Qnil; - rb_module->function_map = NULL; - } - - return rb_module; - } + return rb_loader_impl_create_module(name_capitalized, module, module_data, result); } } } @@ -1495,7 +1570,7 @@ void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_ for (method_index = 0; method_index < methods_size; ++method_index) { VALUE rb_method = rb_ary_entry(methods, method_index); - VALUE name = rb_funcallv(rb_method, rb_intern("id2name"), 0, NULL); + 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); @@ -1540,7 +1615,7 @@ void rb_loader_impl_discover_methods(klass c, VALUE cls, const char *class_name_ if (RARRAY_LEN(parameter_pair) == 2) { VALUE parameter_name_id = rb_ary_entry(parameter_pair, 1); - VALUE parameter_name = rb_funcallv(parameter_name_id, rb_intern("id2name"), 0, NULL); + 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); @@ -1561,7 +1636,7 @@ void rb_loader_impl_discover_attributes(klass c, const char *class_name_str, VAL for (attributes_index = 0; attributes_index < attributes_size; ++attributes_index) { VALUE rb_attr = rb_ary_entry(attributes, attributes_index); - VALUE name = rb_funcallv(rb_attr, rb_intern("id2name"), 0, NULL); + VALUE name = rb_sym2str(rb_attr); const char *attr_name_str = RSTRING_PTR(name); log_write("metacall", LOG_LEVEL_DEBUG, "Attribute '%s' inside '%s'", attr_name_str, class_name_str); @@ -1576,15 +1651,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); @@ -1595,12 +1667,9 @@ int rb_loader_impl_discover_module(loader_impl impl, loader_impl_rb_module rb_mo if (method != Qnil) { - VALUE method_name = rb_funcallv(method, rb_intern("id2name"), 0, NULL); - + VALUE method_name = rb_sym2str(method); const char *method_name_str = RSTRING_PTR(method_name); - rb_function_parser function_parser = set_get(rb_module->function_map, (set_key)method_name_str); - loader_impl_rb_function rb_function = NULL; if (function_parser == NULL) @@ -1622,7 +1691,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 { @@ -1632,12 +1701,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); } } } @@ -1651,80 +1720,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_funcallv(constant, rb_intern("id2name"), 0, NULL); - 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] = { 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); - 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, "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, "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, "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) @@ -1750,10 +1845,15 @@ int rb_loader_impl_discover(loader_impl impl, loader_handle handle, context ctx) int rb_loader_impl_destroy(loader_impl impl) { - (void)impl; + const int host = loader_impl_get_option_host(impl); /* Destroy children loaders */ loader_unload_children(impl); + if (host == 1) + { + return 0; + } + return ruby_cleanup(0); } diff --git a/source/loaders/rb_loader/source/rb_loader_impl_parser.c b/source/loaders/rb_loader/source/rb_loader_impl_parser.c index dc8cd5dde2..c2780bc209 100644 --- a/source/loaders/rb_loader/source/rb_loader_impl_parser.c +++ b/source/loaders/rb_loader/source/rb_loader_impl_parser.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,12 +42,6 @@ enum rb_loader_impl_comment_state rb_loader_impl_comment_state_multi_line_end }; -/* -- Private Methods -- */ - -static int rb_loader_impl_key_print_cb_iterate(set s, set_key key, set_value v, set_cb_iterate_args args); - -static int rb_loader_impl_key_clear_cb_iterate(set s, set_key key, set_value v, set_cb_iterate_args args); - /* -- Methods -- */ int rb_loader_impl_key_parse(const char *source, set function_map) @@ -396,53 +390,38 @@ int rb_loader_impl_key_parse(const char *source, set function_map) return 0; } -int rb_loader_impl_key_print_cb_iterate(set s, set_key key, set_value v, set_cb_iterate_args args) +void rb_loader_impl_key_print(set function_map) { - size_t parameter; + struct set_iterator_type it; - rb_function_parser function = v; + for (set_iterator_begin(&it, function_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + size_t parameter; - (void)s; - (void)key; - (void)args; + rb_function_parser function = set_iterator_value(&it); - log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader key parse function (%s)", function->name); + log_write("metacall", LOG_LEVEL_DEBUG, "Ruby loader key parse function (%s)", function->name); - for (parameter = 0; parameter < function->params_size; ++parameter) - { - log_write("metacall", LOG_LEVEL_DEBUG, " Ruby loader key parse parameter [%d] (%s : %s)", - function->params[parameter].index, - function->params[parameter].name, - function->params[parameter].type); + for (parameter = 0; parameter < function->params_size; ++parameter) + { + log_write("metacall", LOG_LEVEL_DEBUG, " Ruby loader key parse parameter [%d] (%s : %s)", + function->params[parameter].index, + function->params[parameter].name, + function->params[parameter].type); + } } - - return 0; } -void rb_loader_impl_key_print(set function_map) -{ - set_iterate(function_map, &rb_loader_impl_key_print_cb_iterate, NULL); -} - -int rb_loader_impl_key_clear_cb_iterate(set s, set_key key, set_value v, set_cb_iterate_args args) +void rb_loader_impl_key_clear(set function_map) { - rb_function_parser function = v; + struct set_iterator_type it; - (void)s; - (void)key; - (void)args; - - if (function != NULL) + for (set_iterator_begin(&it, function_map); set_iterator_end(&it) != 0; set_iterator_next(&it)) { + rb_function_parser function = set_iterator_value(&it); + free(function); } - return 0; -} - -void rb_loader_impl_key_clear(set function_map) -{ - set_iterate(function_map, &rb_loader_impl_key_clear_cb_iterate, NULL); - set_destroy(function_map); } diff --git a/source/loaders/rb_loader/source/rb_loader_port.c b/source/loaders/rb_loader/source/rb_loader_port.c new file mode 100644 index 0000000000..18f957f0d6 --- /dev/null +++ b/source/loaders/rb_loader/source/rb_loader_port.c @@ -0,0 +1,275 @@ +/* + * 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 + * + * 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 +#include + +#include + +#include + +#include + +static loader_impl rb_loader_impl = NULL; + +static VALUE rb_loader_port_load_from_file(VALUE self, VALUE tag_value, VALUE paths_value) +{ + const char *tag; + const char **paths; + size_t size; + int result; + + (void)self; + + /* Get tag */ + if (TYPE(tag_value) != T_STRING) + { + rb_raise(rb_eArgError, "First parameter expected to be a string indicating the tag of the loader (py, node, c, ...)"); + return Qnil; + } + + tag = StringValuePtr(tag_value); + + /* Get array size */ + if (TYPE(paths_value) != T_ARRAY) + { + rb_raise(rb_eArgError, "Second parameter expected to be an array of strings with the desired files to be loaded"); + return Qnil; + } + + size = RARRAY_LEN(paths_value); + + if (size == 0) + { + rb_raise(rb_eArgError, "Second parameter cannot be an empty file path list"); + return Qnil; + } + + /* Parse the array */ + { + size_t iterator; + VALUE *array_ptr = RARRAY_PTR(paths_value); + + paths = (const char **)malloc(sizeof(const char *) * size); + + if (paths == NULL) + { + rb_raise(rb_eArgError, "Invalid paths argument allocation"); + return Qnil; + } + + for (iterator = 0; iterator < size; ++iterator) + { + if (TYPE(array_ptr[iterator]) != T_STRING) + { + rb_raise(rb_eArgError, "Second parameter expected to be an array of strings, but the element %" PRIuS " of the array is not a string", iterator); + free(paths); + return Qnil; + } + + paths[iterator] = StringValuePtr(array_ptr[iterator]); + } + } + + /* Execute load from file */ + result = metacall_load_from_file(tag, (const char **)paths, size, NULL); + + free(paths); + + return LONG2NUM(result); +} + +static VALUE rb_loader_port_load_from_memory(VALUE self, VALUE tag_value, VALUE buffer_value) +{ + const char *tag; + const char *buffer; + size_t size; + int result; + + (void)self; + + /* Get tag */ + if (TYPE(tag_value) != T_STRING) + { + rb_raise(rb_eArgError, "First parameter expected to be a string indicating the tag of the loader (py, node, c, ...)"); + return Qnil; + } + + tag = StringValuePtr(tag_value); + + /* Get buffer size */ + if (TYPE(buffer_value) != T_STRING) + { + rb_raise(rb_eArgError, "Second parameter expected to be an string with the code to be loaded"); + return Qnil; + } + + size = RSTRING_LEN(buffer_value) + 1; + + if (size == 1) + { + rb_raise(rb_eArgError, "Second parameter cannot be an empty string"); + return Qnil; + } + + /* Get buffer */ + buffer = StringValuePtr(buffer_value); + + /* Execute load from memory */ + result = metacall_load_from_memory(tag, buffer, size, NULL); + + return LONG2NUM(result); +} + +static VALUE rb_loader_port_metacall(int argc, VALUE *argv, VALUE self) +{ + const char *function_name; + size_t args_size, iterator; + value *args, result; + + (void)self; + + if (argc <= 0) + { + rb_raise(rb_eArgError, "Wrong # of arguments (expected at least 1 argument, received 0)"); + return Qnil; + } + + /* Get function name */ + if (TYPE(argv[0]) != T_STRING) + { + rb_raise(rb_eArgError, "First parameter expected to be a string indicating the function name to be called"); + return Qnil; + } + + function_name = StringValuePtr(argv[0]); + + /* Allocate arguments */ + args_size = argc - 1; + + args = args_size > 0 ? (value *)malloc(sizeof(value) * args_size) : metacall_null_args; + + if (args_size > 0 && args == NULL) + { + rb_raise(rb_eArgError, "Invalid arguments allocation"); + return Qnil; + } + + /* Convert the arguments into MetaCall values */ + for (iterator = 0; iterator < args_size; ++iterator) + { + (void)rb_type_deserialize(rb_loader_impl, argv[iterator + 1], &args[iterator]); + } + + /* Execute the call */ + result = metacallv_s(function_name, args, args_size); + + /* Clear the arguments */ + if (args_size > 0) + { + for (iterator = 0; iterator < args_size; ++iterator) + { + value_type_destroy(args[iterator]); + } + + free(args); + } + + return rb_type_serialize(result); +} + +static VALUE rb_loader_port_inspect(VALUE self) +{ + VALUE result; + size_t size = 0; + char *result_str = NULL, *inspect_str = NULL; + struct metacall_allocator_std_type std_ctx = { &malloc, &realloc, &free }; + + /* Create the allocator */ + void *allocator = metacall_allocator_create(METACALL_ALLOCATOR_STD, (void *)&std_ctx); + + (void)self; + + /* Retrieve inspect data */ + result_str = inspect_str = metacall_inspect(&size, allocator); + + if (inspect_str == NULL || size == 0) + { + static const char empty[] = "{}"; + + result_str = (char *)empty; + size = sizeof(empty); + + rb_raise(rb_eArgError, "Inspect returned an invalid size or string"); + } + + result = rb_str_new(result_str, size - 1); + + if (inspect_str != NULL && size > 0) + { + metacall_allocator_free(allocator, inspect_str); + } + + metacall_allocator_destroy(allocator); + + 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; + + if (impl == NULL) + { + return 1; + } + + if (rb_loader_impl != NULL) + { + return 0; + } + + rb_loader_port = rb_define_module("MetaCallRbLoaderPort"); + rb_define_module_function(rb_loader_port, "metacall_load_from_file", rb_loader_port_load_from_file, 2); + 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; + + return 0; +} diff --git a/source/loaders/rpc_loader/CMakeLists.txt b/source/loaders/rpc_loader/CMakeLists.txt index 9ebdc58c07..8cbb72f128 100644 --- a/source/loaders/rpc_loader/CMakeLists.txt +++ b/source/loaders/rpc_loader/CMakeLists.txt @@ -171,7 +171,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h index de574b4b81..a5d71dca59 100644 --- a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h +++ b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rpc endpoints at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RPC_LOADER_API loader_impl_interface rpc_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rpc_loader_impl_interface_singleton); - RPC_LOADER_API const char *rpc_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rpc_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader_impl.h b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader_impl.h index 12d580e6a9..85e9d9fde2 100644 --- a/source/loaders/rpc_loader/include/rpc_loader/rpc_loader_impl.h +++ b/source/loaders/rpc_loader/include/rpc_loader/rpc_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rpc endpoints at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/rpc_loader/source/rpc_loader.c b/source/loaders/rpc_loader/source/rpc_loader.c index c5fb1cba6f..91055fbf57 100644 --- a/source/loaders/rpc_loader/source/rpc_loader.c +++ b/source/loaders/rpc_loader/source/rpc_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rpc endpoints at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *rpc_loader_print_info(void) { static const char rpc_loader_info[] = "RPC Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef RPC_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/rpc_loader/source/rpc_loader_impl.cpp b/source/loaders/rpc_loader/source/rpc_loader_impl.cpp index 4ae44faf2f..abb4b55aa4 100644 --- a/source/loaders/rpc_loader/source/rpc_loader_impl.cpp +++ b/source/loaders/rpc_loader/source/rpc_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rpc endpoints at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use thiz file except in compliance with the License. diff --git a/source/loaders/rs_loader/CMakeLists.txt b/source/loaders/rs_loader/CMakeLists.txt index e6b4bbcff3..aa84cbcce5 100644 --- a/source/loaders/rs_loader/CMakeLists.txt +++ b/source/loaders/rs_loader/CMakeLists.txt @@ -177,7 +177,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/rs_loader/include/rs_loader/rs_loader.h b/source/loaders/rs_loader/include/rs_loader/rs_loader.h index 75f961a332..6d8a75468d 100644 --- a/source/loaders/rs_loader/include/rs_loader/rs_loader.h +++ b/source/loaders/rs_loader/include/rs_loader/rs_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rust code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif RS_LOADER_API loader_impl_interface rs_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rs_loader_impl_interface_singleton); - RS_LOADER_API const char *rs_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(rs_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/rs_loader/include/rs_loader/rs_loader_impl.h b/source/loaders/rs_loader/include/rs_loader/rs_loader_impl.h index 1f34c30487..3890545e57 100644 --- a/source/loaders/rs_loader/include/rs_loader/rs_loader_impl.h +++ b/source/loaders/rs_loader/include/rs_loader/rs_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rust code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/rs_loader/source/rs_loader.c b/source/loaders/rs_loader/source/rs_loader.c index dc8317e360..3bd6062539 100644 --- a/source/loaders/rs_loader/source/rs_loader.c +++ b/source/loaders/rs_loader/source/rs_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading rust code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ const char *rs_loader_print_info(void) { static const char rs_loader_info[] = "Rust Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef RS_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/ts_loader/CMakeLists.txt b/source/loaders/ts_loader/CMakeLists.txt index 4869091dd1..b761122500 100644 --- a/source/loaders/ts_loader/CMakeLists.txt +++ b/source/loaders/ts_loader/CMakeLists.txt @@ -164,7 +164,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/ts_loader/include/ts_loader/ts_loader.h b/source/loaders/ts_loader/include/ts_loader/ts_loader.h index 812c4c2496..e30ce52c3f 100644 --- a/source/loaders/ts_loader/include/ts_loader/ts_loader.h +++ b/source/loaders/ts_loader/include/ts_loader/ts_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading TypeScript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif TS_LOADER_API loader_impl_interface ts_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(ts_loader_impl_interface_singleton); - TS_LOADER_API const char *ts_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(ts_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/ts_loader/include/ts_loader/ts_loader_impl.h b/source/loaders/ts_loader/include/ts_loader/ts_loader_impl.h index d96bb82356..1cab73388c 100644 --- a/source/loaders/ts_loader/include/ts_loader/ts_loader_impl.h +++ b/source/loaders/ts_loader/include/ts_loader/ts_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading TypeScript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/ts_loader/source/ts_loader.c b/source/loaders/ts_loader/source/ts_loader.c index b93b632b33..2afd1d79c9 100644 --- a/source/loaders/ts_loader/source/ts_loader.c +++ b/source/loaders/ts_loader/source/ts_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading TypeScript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *ts_loader_print_info(void) { static const char ts_loader_info[] = "TypeScript Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef TS_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/ts_loader/source/ts_loader_impl.cpp b/source/loaders/ts_loader/source/ts_loader_impl.cpp index 6be97f9f0a..57f9a42f0a 100644 --- a/source/loaders/ts_loader/source/ts_loader_impl.cpp +++ b/source/loaders/ts_loader/source/ts_loader_impl.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading TypeScript code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/wasm_loader/CMakeLists.txt b/source/loaders/wasm_loader/CMakeLists.txt index 1dd721fec9..c51d56713e 100644 --- a/source/loaders/wasm_loader/CMakeLists.txt +++ b/source/loaders/wasm_loader/CMakeLists.txt @@ -174,7 +174,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h index b34e2a5d10..a7f481ffd1 100644 --- a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h +++ b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,20 +25,14 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif WASM_LOADER_API loader_impl_interface wasm_loader_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(wasm_loader_impl_interface_singleton); - WASM_LOADER_API const char *wasm_loader_print_info(void); -DYNLINK_SYMBOL_EXPORT(wasm_loader_print_info); - #ifdef __cplusplus } #endif diff --git a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_function.h b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_function.h index a8a59fd64f..a427503b9f 100644 --- a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_function.h +++ b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_function.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_handle.h b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_handle.h index e775e00762..411aa0095f 100644 --- a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_handle.h +++ b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_handle.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_impl.h b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_impl.h index 8750a55158..de0c630005 100644 --- a/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_impl.h +++ b/source/loaders/wasm_loader/include/wasm_loader/wasm_loader_impl.h @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/loaders/wasm_loader/source/wasm_loader.c b/source/loaders/wasm_loader/source/wasm_loader.c index f28af43b83..6ac5fbabce 100644 --- a/source/loaders/wasm_loader/source/wasm_loader.c +++ b/source/loaders/wasm_loader/source/wasm_loader.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ const char *wasm_loader_print_info(void) { static const char wasm_loader_info[] = "WebAssembly Loader Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef wasm_LOADER_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/loaders/wasm_loader/source/wasm_loader_impl.c b/source/loaders/wasm_loader/source/wasm_loader_impl.c index 3073bb4f13..d359ef872f 100644 --- a/source/loaders/wasm_loader/source/wasm_loader_impl.c +++ b/source/loaders/wasm_loader/source/wasm_loader_impl.c @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading WebAssembly code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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 diff --git a/source/log/CMakeLists.txt b/source/log/CMakeLists.txt index becaf85fbd..bce9dc5938 100644 --- a/source/log/CMakeLists.txt +++ b/source/log/CMakeLists.txt @@ -180,6 +180,7 @@ target_link_libraries(${target} ${META_PROJECT_NAME}::preprocessor ${META_PROJECT_NAME}::format ${META_PROJECT_NAME}::threading + ${META_PROJECT_NAME}::portability PUBLIC ${DEFAULT_LIBRARIES} @@ -219,7 +220,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/log/include/log/log.h b/source/log/include/log/log.h index f39afdb646..784b605552 100644 --- a/source/log/include/log/log.h +++ b/source/log/include/log/log.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_aspect.h b/source/log/include/log/log_aspect.h index 9112d29d66..649dd56fa4 100644 --- a/source/log/include/log/log_aspect.h +++ b/source/log/include/log/log_aspect.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_aspect_format.h b/source/log/include/log/log_aspect_format.h index da4ef2ca27..9f0804491f 100644 --- a/source/log/include/log/log_aspect_format.h +++ b/source/log/include/log/log_aspect_format.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_aspect_schedule.h b/source/log/include/log/log_aspect_schedule.h index 96c04c7ba7..9345d498ea 100644 --- a/source/log/include/log/log_aspect_schedule.h +++ b/source/log/include/log/log_aspect_schedule.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_aspect_storage.h b/source/log/include/log/log_aspect_storage.h index c7909bbe46..dba9475765 100644 --- a/source/log/include/log/log_aspect_storage.h +++ b/source/log/include/log/log_aspect_storage.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_aspect_stream.h b/source/log/include/log/log_aspect_stream.h index e667ba6eb3..4a9fe93b0d 100644 --- a/source/log/include/log/log_aspect_stream.h +++ b/source/log/include/log/log_aspect_stream.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_handle.h b/source/log/include/log/log_handle.h index f5c1256c98..24fbe66332 100644 --- a/source/log/include/log/log_handle.h +++ b/source/log/include/log/log_handle.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_impl.h b/source/log/include/log/log_impl.h index 49121ef1dd..567ac35589 100644 --- a/source/log/include/log/log_impl.h +++ b/source/log/include/log/log_impl.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_level.h b/source/log/include/log/log_level.h index 02598159c9..fe5658d16c 100644 --- a/source/log/include/log/log_level.h +++ b/source/log/include/log/log_level.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_map.h b/source/log/include/log/log_map.h index 58504eef0f..91a8388c08 100644 --- a/source/log/include/log/log_map.h +++ b/source/log/include/log/log_map.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy.h b/source/log/include/log/log_policy.h index 2340673c3c..b0d558cb86 100644 --- a/source/log/include/log/log_policy.h +++ b/source/log/include/log/log_policy.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_policy_format.h b/source/log/include/log/log_policy_format.h index d31fc18747..9047688c06 100644 --- a/source/log/include/log/log_policy_format.h +++ b/source/log/include/log/log_policy_format.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_format_binary.h b/source/log/include/log/log_policy_format_binary.h index f2811526e7..896ba96ffa 100644 --- a/source/log/include/log/log_policy_format_binary.h +++ b/source/log/include/log/log_policy_format_binary.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_format_custom.h b/source/log/include/log/log_policy_format_custom.h index e58d96c73d..4112ab177d 100644 --- a/source/log/include/log/log_policy_format_custom.h +++ b/source/log/include/log/log_policy_format_custom.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_format_text.h b/source/log/include/log/log_policy_format_text.h index 83e041a74f..f764fa6ec5 100644 --- a/source/log/include/log/log_policy_format_text.h +++ b/source/log/include/log/log_policy_format_text.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_schedule.h b/source/log/include/log/log_policy_schedule.h index 85d2121355..c3a53c0d21 100644 --- a/source/log/include/log/log_policy_schedule.h +++ b/source/log/include/log/log_policy_schedule.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_schedule_async.h b/source/log/include/log/log_policy_schedule_async.h index 1acc0992aa..92826e61bf 100644 --- a/source/log/include/log/log_policy_schedule_async.h +++ b/source/log/include/log/log_policy_schedule_async.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_schedule_sync.h b/source/log/include/log/log_policy_schedule_sync.h index dea6dc2a15..451b20ce4c 100644 --- a/source/log/include/log/log_policy_schedule_sync.h +++ b/source/log/include/log/log_policy_schedule_sync.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_storage.h b/source/log/include/log/log_policy_storage.h index 21ed8cb437..04ba13e6e1 100644 --- a/source/log/include/log/log_policy_storage.h +++ b/source/log/include/log/log_policy_storage.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_storage_batch.h b/source/log/include/log/log_policy_storage_batch.h index cb5839a82d..6f14bbd3fd 100644 --- a/source/log/include/log/log_policy_storage_batch.h +++ b/source/log/include/log/log_policy_storage_batch.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_storage_sequential.h b/source/log/include/log/log_policy_storage_sequential.h index 6ec9c39c72..7233f2dba7 100644 --- a/source/log/include/log/log_policy_storage_sequential.h +++ b/source/log/include/log/log_policy_storage_sequential.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream.h b/source/log/include/log/log_policy_stream.h index 2bd99a4c5c..239e646f10 100644 --- a/source/log/include/log/log_policy_stream.h +++ b/source/log/include/log/log_policy_stream.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_custom.h b/source/log/include/log/log_policy_stream_custom.h index e8d718fbba..7322e1f4c4 100644 --- a/source/log/include/log/log_policy_stream_custom.h +++ b/source/log/include/log/log_policy_stream_custom.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_file.h b/source/log/include/log/log_policy_stream_file.h index d901f49163..466195f479 100644 --- a/source/log/include/log/log_policy_stream_file.h +++ b/source/log/include/log/log_policy_stream_file.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_nginx.h b/source/log/include/log/log_policy_stream_nginx.h index 70d0da145a..22eb7036df 100644 --- a/source/log/include/log/log_policy_stream_nginx.h +++ b/source/log/include/log/log_policy_stream_nginx.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_socket.h b/source/log/include/log/log_policy_stream_socket.h index 3fc5932975..be98efbe07 100644 --- a/source/log/include/log/log_policy_stream_socket.h +++ b/source/log/include/log/log_policy_stream_socket.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_stdio.h b/source/log/include/log/log_policy_stream_stdio.h index 20d118796d..dd6f543c94 100644 --- a/source/log/include/log/log_policy_stream_stdio.h +++ b/source/log/include/log/log_policy_stream_stdio.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_policy_stream_syslog.h b/source/log/include/log/log_policy_stream_syslog.h index 558e5de775..a5fab536d9 100644 --- a/source/log/include/log/log_policy_stream_syslog.h +++ b/source/log/include/log/log_policy_stream_syslog.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_preprocessor.h b/source/log/include/log/log_preprocessor.h index e2dfb62dc6..66676cd21d 100644 --- a/source/log/include/log/log_preprocessor.h +++ b/source/log/include/log/log_preprocessor.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/include/log/log_record.h b/source/log/include/log/log_record.h index 4250471e39..c93967af7b 100644 --- a/source/log/include/log/log_record.h +++ b/source/log/include/log/log_record.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_singleton.h b/source/log/include/log/log_singleton.h index 23edd30a8e..31dce2ddb4 100644 --- a/source/log/include/log/log_singleton.h +++ b/source/log/include/log/log_singleton.h @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/include/log/log_valid_size.h b/source/log/include/log/log_valid_size.h index d822da16ae..29cfdd547b 100644 --- a/source/log/include/log/log_valid_size.h +++ b/source/log/include/log/log_valid_size.h @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log.c b/source/log/source/log.c index 3d22b45416..6643b7b89d 100644 --- a/source/log/source/log.c +++ b/source/log/source/log.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -248,7 +248,7 @@ const char *log_print_info(void) { static const char log_info[] = "Logger Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef LOG_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/log/source/log_aspect.c b/source/log/source/log_aspect.c index aeb11efe5b..360077dc8a 100644 --- a/source/log/source/log_aspect.c +++ b/source/log/source/log_aspect.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log_aspect_format.c b/source/log/source/log_aspect_format.c index 4aa81b0cca..f28dfe262c 100644 --- a/source/log/source/log_aspect_format.c +++ b/source/log/source/log_aspect_format.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_aspect_schedule.c b/source/log/source/log_aspect_schedule.c index d951f8aee0..421d6e9ecb 100644 --- a/source/log/source/log_aspect_schedule.c +++ b/source/log/source/log_aspect_schedule.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_aspect_storage.c b/source/log/source/log_aspect_storage.c index ce23ac8914..f6ffeb15d8 100644 --- a/source/log/source/log_aspect_storage.c +++ b/source/log/source/log_aspect_storage.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_aspect_stream.c b/source/log/source/log_aspect_stream.c index 01cfac3616..2a1aaa57da 100644 --- a/source/log/source/log_aspect_stream.c +++ b/source/log/source/log_aspect_stream.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_handle.c b/source/log/source/log_handle.c index e79c9a1ddd..ff691fc45d 100644 --- a/source/log/source/log_handle.c +++ b/source/log/source/log_handle.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log_impl.c b/source/log/source/log_impl.c index 875321d73a..6b412c20cd 100644 --- a/source/log/source/log_impl.c +++ b/source/log/source/log_impl.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log_level.c b/source/log/source/log_level.c index 17b453dbe6..a11a790af3 100644 --- a/source/log/source/log_level.c +++ b/source/log/source/log_level.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log_map.c b/source/log/source/log_map.c index 6bbbcc569f..8796e0515a 100644 --- a/source/log/source/log_map.c +++ b/source/log/source/log_map.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy.c b/source/log/source/log_policy.c index 5afce576a2..7b569330a0 100644 --- a/source/log/source/log_policy.c +++ b/source/log/source/log_policy.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/log/source/log_policy_format.c b/source/log/source/log_policy_format.c index a54e306f9e..f02907228a 100644 --- a/source/log/source/log_policy_format.c +++ b/source/log/source/log_policy_format.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_format_binary.c b/source/log/source/log_policy_format_binary.c index 3730e91f1e..4c4774521f 100644 --- a/source/log/source/log_policy_format_binary.c +++ b/source/log/source/log_policy_format_binary.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_format_custom.c b/source/log/source/log_policy_format_custom.c index 7cb4b8a93c..459eb9437d 100644 --- a/source/log/source/log_policy_format_custom.c +++ b/source/log/source/log_policy_format_custom.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_format_text.c b/source/log/source/log_policy_format_text.c index 0ae0e13ed5..7f30cae362 100644 --- a/source/log/source/log_policy_format_text.c +++ b/source/log/source/log_policy_format_text.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * @@ -20,8 +20,8 @@ /* -- Definitions -- */ -#define LOG_POLICY_FORMAT_TEXT_STR_DEBUG "[%.19s] #%" PRIuS " [ %" PRIuS " | %s | %s ] @%s : " -#define LOG_POLICY_FORMAT_TEXT_STR_RELEASE "[%.19s] #%" PRIuS " @%s : " +#define LOG_POLICY_FORMAT_TEXT_STR_DEBUG "[%.19s] #%" PRIu64 " [ %" PRIuS " | %s | %s ] @%s : " +#define LOG_POLICY_FORMAT_TEXT_STR_RELEASE "[%.19s] #%" PRIu64 " @%s : " #define LOG_POLICY_FORMAT_TEXT_STR_PRETTY "\x1b[32m%s\x1b[0m: " /* -- Macros -- */ diff --git a/source/log/source/log_policy_schedule.c b/source/log/source/log_policy_schedule.c index 211400762b..491b7111ef 100644 --- a/source/log/source/log_policy_schedule.c +++ b/source/log/source/log_policy_schedule.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_schedule_async.c b/source/log/source/log_policy_schedule_async.c index 27f0ba3f2c..a3164f2992 100644 --- a/source/log/source/log_policy_schedule_async.c +++ b/source/log/source/log_policy_schedule_async.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_schedule_sync.c b/source/log/source/log_policy_schedule_sync.c index 9d6c78b608..1e5683f2ff 100644 --- a/source/log/source/log_policy_schedule_sync.c +++ b/source/log/source/log_policy_schedule_sync.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_storage.c b/source/log/source/log_policy_storage.c index 9a95e52a1b..9f73737903 100644 --- a/source/log/source/log_policy_storage.c +++ b/source/log/source/log_policy_storage.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_storage_batch.c b/source/log/source/log_policy_storage_batch.c index d34f9e7941..c763875ea1 100644 --- a/source/log/source/log_policy_storage_batch.c +++ b/source/log/source/log_policy_storage_batch.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_storage_sequential.c b/source/log/source/log_policy_storage_sequential.c index 1abb17e270..20ef428a06 100644 --- a/source/log/source/log_policy_storage_sequential.c +++ b/source/log/source/log_policy_storage_sequential.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream.c b/source/log/source/log_policy_stream.c index 1792d80b69..fa65c9504c 100644 --- a/source/log/source/log_policy_stream.c +++ b/source/log/source/log_policy_stream.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_custom.c b/source/log/source/log_policy_stream_custom.c index d20bd4761e..de0a61789e 100644 --- a/source/log/source/log_policy_stream_custom.c +++ b/source/log/source/log_policy_stream_custom.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_file.c b/source/log/source/log_policy_stream_file.c index 8453d46fb1..28770a67d8 100644 --- a/source/log/source/log_policy_stream_file.c +++ b/source/log/source/log_policy_stream_file.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_nginx.c b/source/log/source/log_policy_stream_nginx.c index 5309c1408e..6d75b49375 100644 --- a/source/log/source/log_policy_stream_nginx.c +++ b/source/log/source/log_policy_stream_nginx.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_socket.c b/source/log/source/log_policy_stream_socket.c index bc99b80e48..d433286de4 100644 --- a/source/log/source/log_policy_stream_socket.c +++ b/source/log/source/log_policy_stream_socket.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_stdio.c b/source/log/source/log_policy_stream_stdio.c index 610a2c5e4f..cea63699dd 100644 --- a/source/log/source/log_policy_stream_stdio.c +++ b/source/log/source/log_policy_stream_stdio.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_policy_stream_syslog.c b/source/log/source/log_policy_stream_syslog.c index 22aefbef11..3cae6c9f0a 100644 --- a/source/log/source/log_policy_stream_syslog.c +++ b/source/log/source/log_policy_stream_syslog.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_record.c b/source/log/source/log_record.c index bdb6f2a6cb..f99237b630 100644 --- a/source/log/source/log_record.c +++ b/source/log/source/log_record.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * diff --git a/source/log/source/log_singleton.c b/source/log/source/log_singleton.c index 39d326e64e..63e63f2d01 100644 --- a/source/log/source/log_singleton.c +++ b/source/log/source/log_singleton.c @@ -1,6 +1,6 @@ /* * Logger Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * A generic logger library providing application execution reports. * @@ -9,6 +9,8 @@ #include #include +#include + #include /* -- Definitions -- */ @@ -98,7 +100,10 @@ log_singleton log_singleton_instance_impl(void) abort(); } - if (atexit(&log_atexit_callback) != 0) + /* Initialize at exit handlers */ + portability_atexit_initialize(); + + if (portability_atexit_register(&log_atexit_callback) != 0) { if (log_singleton_destroy() != 0) { diff --git a/source/log/source/log_valid_size.c b/source/log/source/log_valid_size.c index 5583c000c2..96db31c69e 100644 --- a/source/log/source/log_valid_size.c +++ b/source/log/source/log_valid_size.c @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/CMakeLists.txt b/source/memory/CMakeLists.txt index fa7b05c039..043812e4ad 100644 --- a/source/memory/CMakeLists.txt +++ b/source/memory/CMakeLists.txt @@ -161,7 +161,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/memory/include/memory/memory.h b/source/memory/include/memory/memory.h index e1ce6a244f..ec664adb5a 100644 --- a/source/memory/include/memory/memory.h +++ b/source/memory/include/memory/memory.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator.h b/source/memory/include/memory/memory_allocator.h index b8448027ea..668177a07f 100644 --- a/source/memory/include/memory/memory_allocator.h +++ b/source/memory/include/memory/memory_allocator.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_iface.h b/source/memory/include/memory/memory_allocator_iface.h index 9249b263b6..b87cf8c980 100644 --- a/source/memory/include/memory/memory_allocator_iface.h +++ b/source/memory/include/memory/memory_allocator_iface.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_impl.h b/source/memory/include/memory/memory_allocator_impl.h index 73c4369b22..5476e6a3ef 100644 --- a/source/memory/include/memory/memory_allocator_impl.h +++ b/source/memory/include/memory/memory_allocator_impl.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_nginx.h b/source/memory/include/memory/memory_allocator_nginx.h index 4bb005c0a1..2e35fd648b 100644 --- a/source/memory/include/memory/memory_allocator_nginx.h +++ b/source/memory/include/memory/memory_allocator_nginx.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_nginx_impl.h b/source/memory/include/memory/memory_allocator_nginx_impl.h index 73aa5a4f20..b2dff3bb2a 100644 --- a/source/memory/include/memory/memory_allocator_nginx_impl.h +++ b/source/memory/include/memory/memory_allocator_nginx_impl.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_std.h b/source/memory/include/memory/memory_allocator_std.h index 0f27a83fe7..779bce0883 100644 --- a/source/memory/include/memory/memory_allocator_std.h +++ b/source/memory/include/memory/memory_allocator_std.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/include/memory/memory_allocator_std_impl.h b/source/memory/include/memory/memory_allocator_std_impl.h index 20fc8bb451..f25819d550 100644 --- a/source/memory/include/memory/memory_allocator_std_impl.h +++ b/source/memory/include/memory/memory_allocator_std_impl.h @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/source/memory.c b/source/memory/source/memory.c index cb41b078bf..87107f32f2 100644 --- a/source/memory/source/memory.c +++ b/source/memory/source/memory.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ const char *memory_print_info(void) { static const char memory_info[] = "Memory Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef MEMORY_STATIC_DEFINE "Compiled as static library type" diff --git a/source/memory/source/memory_allocator.c b/source/memory/source/memory_allocator.c index c6962d83af..5d853b30a9 100644 --- a/source/memory/source/memory_allocator.c +++ b/source/memory/source/memory_allocator.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/source/memory_allocator_nginx.c b/source/memory/source/memory_allocator_nginx.c index 000dffb4b7..dc5385648d 100644 --- a/source/memory/source/memory_allocator_nginx.c +++ b/source/memory/source/memory_allocator_nginx.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/source/memory_allocator_nginx_impl.c b/source/memory/source/memory_allocator_nginx_impl.c index 5acec5ef1d..cd5534a974 100644 --- a/source/memory/source/memory_allocator_nginx_impl.c +++ b/source/memory/source/memory_allocator_nginx_impl.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/source/memory_allocator_std.c b/source/memory/source/memory_allocator_std.c index 9d5bf58070..ce755c4fd6 100644 --- a/source/memory/source/memory_allocator_std.c +++ b/source/memory/source/memory_allocator_std.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/memory/source/memory_allocator_std_impl.c b/source/memory/source/memory_allocator_std_impl.c index 5d1cebf03f..77b36f8a87 100644 --- a/source/memory/source/memory_allocator_std_impl.c +++ b/source/memory/source/memory_allocator_std_impl.c @@ -2,7 +2,7 @@ * Memory Library by Parra Studios * A generic cross-platform memory utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/CMakeLists.txt b/source/metacall/CMakeLists.txt index 87146dc9b5..25f45878e7 100644 --- a/source/metacall/CMakeLists.txt +++ b/source/metacall/CMakeLists.txt @@ -56,6 +56,7 @@ set(headers ${include_path}/metacall_log.h ${include_path}/metacall_allocator.h ${include_path}/metacall_error.h + ${include_path}/metacall_link.h ) set(sources @@ -64,6 +65,7 @@ set(sources ${source_path}/metacall_log.c ${source_path}/metacall_allocator.c ${source_path}/metacall_error.c + ${source_path}/metacall_link.c ) if(OPTION_FORK_SAFE) @@ -198,6 +200,11 @@ target_link_libraries(${target} PUBLIC ${DEFAULT_LIBRARIES} + $<$:${CMAKE_DL_LIBS}> # Native dynamic load library + + # Fix issues with atomics in armv6 and armv7 + $<$:-latomic> + INTERFACE ) @@ -240,14 +247,12 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC ${DEFAULT_LINKER_OPTIONS} - $<$:${CMAKE_DL_LIBS}> # Native dynamic load library - INTERFACE ) diff --git a/source/metacall/include/metacall/metacall.h b/source/metacall/include/metacall/metacall.h index a1cea928fe..8ef64fd3e6 100644 --- a/source/metacall/include/metacall/metacall.h +++ b/source/metacall/include/metacall/metacall.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -58,10 +59,8 @@ struct metacall_initialize_configuration_type; struct metacall_initialize_configuration_type { - char *tag; - void *options; // TODO: We should use a MetaCall value MAP here and merge it with the configuration. - // By this way loaders will be able to access this information in the backend and we - // can use a weak API in order to implement this successfully + const char *tag; /* Tag referring to the loader */ + void *options; /* Value of type Map that will be merged merged into the configuration of the loader */ }; typedef void *(*metacall_await_callback)(void *, void *); @@ -98,6 +97,15 @@ METACALL_API extern void *metacall_null_args[1]; */ METACALL_API const char *metacall_serial(void); +/** +* @brief +* Returns default detour used by MetaCall +* +* @return +* Name of the detour to be used with detouring methods +*/ +METACALL_API const char *metacall_detour(void); + /** * @brief * Disables MetaCall logs, must be called before @metacall_initialize. @@ -1480,11 +1488,8 @@ METACALL_API const char *metacall_plugin_path(void); /** * @brief * Destroy MetaCall library -* -* @return -* Zero if success, different from zero otherwise */ -METACALL_API int metacall_destroy(void); +METACALL_API void metacall_destroy(void); /** * @brief diff --git a/source/metacall/include/metacall/metacall_allocator.h b/source/metacall/include/metacall/metacall_allocator.h index 46fc614c45..c7d8017c66 100644 --- a/source/metacall/include/metacall/metacall_allocator.h +++ b/source/metacall/include/metacall/metacall_allocator.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/include/metacall/metacall_error.h b/source/metacall/include/metacall/metacall_error.h index e65d5f9865..e17815fbc7 100644 --- a/source/metacall/include/metacall/metacall_error.h +++ b/source/metacall/include/metacall/metacall_error.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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/include/metacall/metacall_fork.h b/source/metacall/include/metacall/metacall_fork.h index 0cbfb86d15..53eb2478ea 100644 --- a/source/metacall/include/metacall/metacall_fork.h +++ b/source/metacall/include/metacall/metacall_fork.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,11 +88,8 @@ METACALL_API void metacall_fork(metacall_pre_fork_callback_ptr pre_callback, met /** * @brief * Unregister fork detours and destroy shared memory -* -* @return -* Zero if success, different from zero otherwise */ -METACALL_API int metacall_fork_destroy(void); +METACALL_API void metacall_fork_destroy(void); #ifdef __cplusplus } diff --git a/source/metacall/include/metacall/metacall_link.h b/source/metacall/include/metacall/metacall_link.h new file mode 100644 index 0000000000..4e023d090d --- /dev/null +++ b/source/metacall/include/metacall/metacall_link.h @@ -0,0 +1,125 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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_LINK_H +#define METACALL_LINK_H 1 + +/* -- Headers -- */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Methods -- */ + +/** +* @brief +* Initialize link detours and allocate shared memory +* +* @return +* Zero if success, different from zero otherwise +*/ +METACALL_API int metacall_link_initialize(void); + +/** +* @brief +* Register a function pointer in order to allow function +* interposition when loading a library, if you register a +* function @symbol called 'foo', when you try to dlsym (or the equivalent +* on every platform), you will get the pointer to @fn, even if +* the symbol does not exist in the library, it will work. +* Function interposition is required in order to hook into runtimes +* and dynamically interpose our functions. +* +* @param[in] tag +* Name of the loader which the @library belongs to +* +* @param[in] library +* Name of the library that is going to be hooked +* +* @param[in] symbol +* Name of the function to be interposed +* +* @param[in] fn +* Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol +* +* @return +* Zero if success, different from zero otherwise +*/ +METACALL_API int metacall_link_register(const char *tag, const char *library, const char *symbol, void (*fn)(void)); + +/** +* @brief +* Register a function pointer in order to allow function +* interposition when loading a library, if you register a +* function @symbol called 'foo', when you try to dlsym (or the equivalent +* on every platform), you will get the pointer to @fn, even if +* the symbol does not exist in the library, it will work. +* Function interposition is required in order to hook into runtimes +* and dynamically interpose our functions. +* +* @param[in] loader +* Pointer to the loader which the @library belongs to +* +* @param[in] library +* Name of the library that is going to be hooked +* +* @param[in] symbol +* Name of the function to be interposed +* +* @param[in] fn +* Function pointer that will be returned by dlsym (or equivalent) when accessing to @symbol +* +* @return +* Zero if success, different from zero otherwise +*/ +METACALL_API int metacall_link_register_loader(void *loader, const char *library, const char *symbol, void (*fn)(void)); + +/** +* @brief +* Remove the hook previously registered +* +* @param[in] tag +* Name of the loader which the @library belongs to +* +* @param[in] library +* Name of the library that is going to be hooked +* +* @param[in] symbol +* Name of the function to be interposed +* +* @return +* Zero if success, different from zero otherwise +*/ +METACALL_API int metacall_link_unregister(const char *tag, const char *library, const char *symbol); + +/** +* @brief +* Unregister link detours and destroy shared memory +*/ +METACALL_API void metacall_link_destroy(void); + +#ifdef __cplusplus +} +#endif + +#endif /* METACALL_LINK_H */ diff --git a/source/metacall/include/metacall/metacall_log.h b/source/metacall/include/metacall/metacall_log.h index ee28ccdbc1..582ed8ea55 100644 --- a/source/metacall/include/metacall/metacall_log.h +++ b/source/metacall/include/metacall/metacall_log.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/include/metacall/metacall_value.h b/source/metacall/include/metacall/metacall_value.h index 932cc75f08..eda910b123 100644 --- a/source/metacall/include/metacall/metacall_value.h +++ b/source/metacall/include/metacall/metacall_value.h @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/metacall_def.h.in b/source/metacall/metacall_def.h.in index 3486a1ceae..3e9d92a83b 100644 --- a/source/metacall/metacall_def.h.in +++ b/source/metacall/metacall_def.h.in @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/source/metacall.c b/source/metacall/source/metacall.c index 45ce6bf0fb..cd73661845 100644 --- a/source/metacall/source/metacall.c +++ b/source/metacall/source/metacall.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,13 @@ #include +#include + #include +#include +#include + #include #include @@ -42,6 +47,7 @@ #define METACALL_ARGS_SIZE 0x10 #define METACALL_SERIAL "rapid_json" +#define METACALL_DETOUR "plthook" /* -- Type Definitions -- */ @@ -67,6 +73,53 @@ static loader_path plugin_path = { 0 }; static int metacall_plugin_extension_load(void); static void *metacallv_method(void *target, const char *name, method_invoke_ptr call, vector v, void *args[], size_t size); static type_id *metacall_type_ids(void *args[], size_t size); +static void metacall_detour_destructor(void); + +/* -- Costructors -- */ + +portability_constructor(metacall_constructor) +{ + if (metacall_initialize_flag == 1) + { + const char *metacall_host = environment_variable_get("METACALL_HOST", NULL); + + /* Initialize at exit handlers */ + portability_atexit_initialize(); + + /* We are running from a different host, initialize the loader of the host + * and redirect it to the existing symbols, also avoiding initialization + * and destruction of the runtime as it is being managed externally to MetaCall */ + if (metacall_host != NULL) + { + static const char host_str[] = "host"; + + struct metacall_initialize_configuration_type config[] = { + { metacall_host, metacall_value_create_map(NULL, 1) }, + { NULL, NULL } + }; + + /* Initialize the loader options with a map defining its options to { "host": true } */ + void **host_tuple, **options_map = metacall_value_to_map(config[0].options); + + options_map[0] = metacall_value_create_array(NULL, 2); + + host_tuple = metacall_value_to_array(options_map[0]); + + host_tuple[0] = metacall_value_create_string(host_str, sizeof(host_str) - 1); + host_tuple[1] = metacall_value_create_bool(1); + + /* Initialize MetaCall with extra options, defining the host properly */ + if (metacall_initialize_ex(config) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall host constructor failed to initialize"); + exit(1); + } + + /* Register the destructor on exit */ + portability_atexit_register(metacall_destroy); + } + } +} /* -- Methods -- */ @@ -77,6 +130,13 @@ const char *metacall_serial(void) return metacall_serial_str; } +const char *metacall_detour(void) +{ + static const char metacall_detour_str[] = METACALL_DETOUR; + + return metacall_detour_str; +} + void metacall_log_null(void) { metacall_log_null_flag = 0; @@ -135,10 +195,34 @@ int metacall_plugin_extension_load(void) return result; } +void metacall_detour_destructor(void) +{ + /* Destroy link */ + metacall_link_destroy(); + + /* Destroy fork */ +#ifdef METACALL_FORK_SAFE + if (metacall_config_flags & METACALL_FLAGS_FORK_SAFE) + { + metacall_fork_destroy(); + } +#endif /* METACALL_FORK_SAFE */ + + /* Destroy detour */ + detour_destroy(); +} + int metacall_initialize(void) { memory_allocator allocator; + if (metacall_initialize_flag == 0) + { + log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall already initialized"); + + return 0; + } + /* Initialize logs by default to stdout if none has been defined */ if (metacall_log_null_flag != 0 && log_size() == 0) { @@ -154,13 +238,6 @@ int metacall_initialize(void) log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall default logger to stdout initialized"); } - if (metacall_initialize_flag == 0) - { - log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall already initialized"); - - return 0; - } - log_write("metacall", LOG_LEVEL_DEBUG, "Initializing MetaCall"); /* Initialize MetaCall version environment variable */ @@ -170,18 +247,31 @@ int metacall_initialize(void) return 1; } -#ifdef METACALL_FORK_SAFE - if (metacall_config_flags & METACALL_FLAGS_FORK_SAFE) + /* Initialize detours */ { - if (metacall_fork_initialize() != 0) + if (detour_initialize() != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid MetaCall fork initialization"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour initialization"); + return 1; } - log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall fork initialized"); - } +#ifdef METACALL_FORK_SAFE + if (metacall_config_flags & METACALL_FLAGS_FORK_SAFE) + { + if (metacall_fork_initialize() != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid MetaCall fork initialization"); + } + + log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall fork initialized"); + } #endif /* METACALL_FORK_SAFE */ + /* Define destructor for detouring (it must be executed at the end to prevent problems with fork mechanisms) */ + portability_atexit_register(metacall_detour_destructor); + } + + /* Initialize configuration and serializer */ allocator = memory_allocator_std(&malloc, &realloc, &free); if (configuration_initialize(metacall_serial(), NULL, allocator) != 0) @@ -219,6 +309,7 @@ int metacall_initialize(void) } } + /* Initialize loader subsystem */ if (loader_initialize() != 0) { configuration_destroy(); @@ -226,6 +317,12 @@ int metacall_initialize(void) return 1; } + /* Initialize link */ + if (metacall_link_initialize() != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "Invalid MetaCall link initialization"); + } + /* Load core plugins */ if (metacall_plugin_extension_load() != 0) { @@ -248,15 +345,12 @@ int metacall_initialize_ex(struct metacall_initialize_configuration_type initial while (!(initialize_config[index].tag == NULL && initialize_config[index].options == NULL)) { - loader_impl impl = loader_get_impl(initialize_config[index].tag); - - if (impl == NULL) + if (loader_set_options(initialize_config[index].tag, initialize_config[index].options) != 0) { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall failed to set options of '%s_loader'", initialize_config[index].tag); return 1; } - loader_set_options(initialize_config[index].tag, initialize_config[index].options); - ++index; } @@ -2246,7 +2340,7 @@ const char *metacall_plugin_path(void) return plugin_path; } -int metacall_destroy(void) +void metacall_destroy(void) { if (metacall_initialize_flag == 0) { @@ -2256,17 +2350,16 @@ int metacall_destroy(void) /* Destroy configurations */ configuration_destroy(); - metacall_initialize_flag = 1; - /* Print stats from functions, classes, objects and exceptions */ reflect_memory_tracker_debug(); /* Set to null the plugin extension and core plugin handles */ plugin_extension_handle = NULL; plugin_core_handle = NULL; - } - return 0; + /* Set initialization flag to destroyed */ + metacall_initialize_flag = 1; + } } const struct metacall_version_type *metacall_version(void) @@ -2325,7 +2418,7 @@ const char *metacall_print_info(void) { static const char metacall_info[] = "MetaCall Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef METACALL_STATIC_DEFINE "Compiled as static library type" diff --git a/source/metacall/source/metacall_allocator.c b/source/metacall/source/metacall_allocator.c index ee88cdd545..7500b9f829 100644 --- a/source/metacall/source/metacall_allocator.c +++ b/source/metacall/source/metacall_allocator.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/source/metacall_error.c b/source/metacall/source/metacall_error.c index e6833fc52c..68829a5ab5 100644 --- a/source/metacall/source/metacall_error.c +++ b/source/metacall/source/metacall_error.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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) diff --git a/source/metacall/source/metacall_fork.c b/source/metacall/source/metacall_fork.c index 8eea459f8e..0c626a96dc 100644 --- a/source/metacall/source/metacall_fork.c +++ b/source/metacall/source/metacall_fork.c @@ -1,9 +1,21 @@ /* * MetaCall Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * * A library for providing a foreign function interface calls. * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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. + * */ /* -- Headers -- */ @@ -17,6 +29,8 @@ #include +/* -- Methods -- */ + #if defined(WIN32) || defined(_WIN32) || \ defined(__CYGWIN__) || defined(__CYGWIN32__) || \ defined(__MINGW32__) || defined(__MINGW64__) @@ -31,10 +45,6 @@ #endif #include -/* -- Definitions -- */ - - #define metacall_fork_pid _getpid - /* -- Type Definitions -- */ typedef long NTSTATUS; @@ -77,8 +87,6 @@ typedef NTSTATUS(NTAPI *RtlCloneUserProcessPtr)(ULONG ProcessFlags, /* -- Methods -- */ -void (*metacall_fork_func(void))(void); - NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, @@ -92,8 +100,6 @@ NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, /* -- Methods -- */ -void (*metacall_fork_func(void))(void); - pid_t metacall_fork_hook(void); #else @@ -102,38 +108,25 @@ pid_t metacall_fork_hook(void); /* -- Private Variables -- */ -static const char metacall_fork_detour_name[] = "funchook"; - -static detour metacall_detour = NULL; - -static detour_handle metacall_detour_handle = NULL; +static detour_handle detour_fork_handle = NULL; static metacall_pre_fork_callback_ptr metacall_pre_fork_callback = NULL; static metacall_post_fork_callback_ptr metacall_post_fork_callback = NULL; -static int metacall_fork_flag = 1; - /* -- Methods -- */ #if defined(WIN32) || defined(_WIN32) || \ defined(__CYGWIN__) || defined(__CYGWIN32__) || \ defined(__MINGW32__) || defined(__MINGW64__) -void (*metacall_fork_func(void))(void) -{ - HMODULE module; - RtlCloneUserProcessPtr clone_ptr; - - module = GetModuleHandle("ntdll.dll"); +typedef RtlCloneUserProcessPtr metacall_fork_trampoline_type; - if (!module) - { - return NULL; - } +static const char metacall_fork_func_name[] = "RtlCloneUserProcess"; +static metacall_fork_trampoline_type metacall_fork_trampoline = NULL; - clone_ptr = (RtlCloneUserProcessPtr)GetProcAddress(module, "RtlCloneUserProcess"); - - return (void (*)(void))clone_ptr; +static detour_handle metacall_fork_handle(detour d) +{ + return detour_load_file(d, "ntdll.dll"); } NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, @@ -142,8 +135,6 @@ NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, HANDLE DebugPort, PRTL_USER_PROCESS_INFORMATION ProcessInformation) { - RtlCloneUserProcessPtr metacall_fork_trampoline = (RtlCloneUserProcessPtr)detour_trampoline(metacall_detour_handle); - metacall_pre_fork_callback_ptr pre_callback = metacall_pre_fork_callback; metacall_post_fork_callback_ptr post_callback = metacall_post_fork_callback; @@ -159,17 +150,14 @@ NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, /* TODO: Context */ if (pre_callback(NULL) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour pre callback invocation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour pre fork callback invocation"); } } log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall process fork auto destroy"); /* Destroy metacall before the fork */ - if (metacall_destroy() != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall fork auto destruction"); - } + metacall_destroy(); /* Execute the real fork */ result = metacall_fork_trampoline(ProcessFlags, ProcessSecurityDescriptor, ThreadSecurityDescriptor, DebugPort, ProcessInformation); @@ -198,7 +186,7 @@ NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, /* TODO: Context */ if (post_callback(_getpid(), NULL) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour post callback invocation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour post fork callback invocation"); } } @@ -210,15 +198,18 @@ NTSTATUS NTAPI metacall_fork_hook(ULONG ProcessFlags, defined(__CYGWIN__) || defined(__CYGWIN32__) || \ (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) -void (*metacall_fork_func(void))(void) +typedef pid_t (*metacall_fork_trampoline_type)(void); + +static const char metacall_fork_func_name[] = "fork"; +static metacall_fork_trampoline_type metacall_fork_trampoline = NULL; + +static detour_handle metacall_fork_handle(detour d) { - return (void (*)(void)) & fork; + return detour_load_file(d, NULL); } pid_t metacall_fork_hook(void) { - pid_t (*metacall_fork_trampoline)(void) = (pid_t(*)(void))detour_trampoline(metacall_detour_handle); - metacall_pre_fork_callback_ptr pre_callback = metacall_pre_fork_callback; metacall_post_fork_callback_ptr post_callback = metacall_post_fork_callback; @@ -234,17 +225,14 @@ pid_t metacall_fork_hook(void) /* TODO: Context */ if (pre_callback(NULL) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour pre callback invocation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour pre fork callback invocation"); } } log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall process fork auto destroy"); /* Destroy metacall before the fork */ - if (metacall_destroy() != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall fork auto destruction fail"); - } + metacall_destroy(); /* Execute the real fork */ pid = metacall_fork_trampoline(); @@ -268,7 +256,7 @@ pid_t metacall_fork_hook(void) /* TODO: Context */ if (post_callback(pid, NULL) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour post callback invocation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour post fork callback invocation"); } } @@ -279,71 +267,40 @@ pid_t metacall_fork_hook(void) #error "Unknown metacall fork safety platform" #endif -static void metacall_fork_exit(void) -{ - log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall atexit triggered"); - - if (metacall_fork_destroy() != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "Invalid MetaCall fork destruction"); - } - - log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall fork destroyed"); -} - int metacall_fork_initialize(void) { - void (*fork_func)(void) = metacall_fork_func(); - - if (fork_func == NULL) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid fork function pointer"); - - return 1; - } + detour d = detour_create(metacall_detour()); - if (detour_initialize() != 0) + if (detour_fork_handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour initialization"); - - return 1; - } + /* Casting for getting the original function */ + union + { + metacall_fork_trampoline_type *trampoline; + void (**ptr)(void); + } cast = { &metacall_fork_trampoline }; - if (metacall_detour == NULL) - { - metacall_detour = detour_create(metacall_fork_detour_name); + detour_fork_handle = metacall_fork_handle(d); - if (metacall_detour == NULL) + if (detour_fork_handle == NULL) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour creation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour fork installation"); metacall_fork_destroy(); return 1; } - } - if (metacall_detour_handle == NULL) - { - metacall_detour_handle = detour_install(metacall_detour, (void (*)(void))fork_func, (void (*)(void)) & metacall_fork_hook); - - if (metacall_detour_handle == NULL) + if (detour_replace(d, detour_fork_handle, metacall_fork_func_name, (void (*)(void))(&metacall_fork_hook), cast.ptr) != 0) { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour installation"); + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour fork replacement"); - metacall_fork_destroy(); + metacall_link_destroy(); return 1; } } - if (metacall_fork_flag == 1) - { - atexit(&metacall_fork_exit); - - metacall_fork_flag = 0; - } - return 0; } @@ -353,38 +310,19 @@ void metacall_fork(metacall_pre_fork_callback_ptr pre_callback, metacall_post_fo metacall_post_fork_callback = post_callback; } -int metacall_fork_destroy(void) +void metacall_fork_destroy(void) { - int result = 0; - - if (metacall_detour_handle != NULL) + if (detour_fork_handle != NULL) { - if (detour_uninstall(metacall_detour, metacall_detour_handle) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour uninstall"); + detour d = detour_create(metacall_detour()); - result = 1; - } + /* TODO: Restore the hook? We need support for this on the detour API */ - metacall_detour_handle = NULL; - } + detour_unload(d, detour_fork_handle); - if (metacall_detour != NULL) - { - if (detour_clear(metacall_detour) != 0) - { - log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid detour clear"); - - result = 1; - } - - metacall_detour = NULL; + detour_fork_handle = NULL; } - detour_destroy(); - metacall_pre_fork_callback = NULL; metacall_post_fork_callback = NULL; - - return result; } diff --git a/source/metacall/source/metacall_link.c b/source/metacall/source/metacall_link.c new file mode 100644 index 0000000000..cc261644e7 --- /dev/null +++ b/source/metacall/source/metacall_link.c @@ -0,0 +1,242 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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. + * + */ + +/* -- Headers -- */ + +#include +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +/* -- Private Variables -- */ + +static set metacall_link_table = NULL; +static threading_mutex_type link_mutex = THREADING_MUTEX_INITIALIZE; + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + + #include + +typedef FARPROC (*metacall_link_trampoline_type)(HMODULE, LPCSTR); + +static const char metacall_link_func_name[] = "GetProcAddress"; +static metacall_link_trampoline_type metacall_link_trampoline = NULL; + +static metacall_link_trampoline_type metacall_link_func(void) +{ + return &GetProcAddress; +} + +FARPROC metacall_link_hook(HMODULE handle, LPCSTR symbol) +{ + void *ptr; + + threading_mutex_lock(&link_mutex); + + /* Intercept if any */ + ptr = set_get(metacall_link_table, (set_key)symbol); + + threading_mutex_unlock(&link_mutex); + + if (ptr != NULL) + { + dynlink_symbol_addr addr; + + dynlink_symbol_cast(void *, ptr, addr); + + return (FARPROC)addr; + } + + return metacall_link_trampoline(handle, symbol); +} + +#elif defined(unix) || defined(__unix__) || defined(__unix) || \ + defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) + + #include + +typedef void *(*metacall_link_trampoline_type)(void *, const char *); + +static const char metacall_link_func_name[] = "dlsym"; +static metacall_link_trampoline_type metacall_link_trampoline = NULL; + +static metacall_link_trampoline_type metacall_link_func(void) +{ + return &dlsym; +} + +void *metacall_link_hook(void *handle, const char *symbol) +{ + void *ptr; + + threading_mutex_lock(&link_mutex); + + /* Intercept function if any */ + ptr = set_get(metacall_link_table, (set_key)symbol); + + /* TODO: Disable logs here until log is completely thread safe and async signal safe */ + /* log_write("metacall", LOG_LEVEL_DEBUG, "MetaCall detour link interception: %s -> %p", symbol, ptr); */ + + threading_mutex_unlock(&link_mutex); + + if (ptr != NULL) + { + return ptr; + } + + return metacall_link_trampoline(handle, symbol); +} + +#else + #error "Unknown metacall link platform" +#endif + +/* -- Methods -- */ + +int metacall_link_initialize(void) +{ + if (threading_mutex_initialize(&link_mutex) != 0) + { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall invalid link mutex initialization"); + + return 1; + } + + /* Initialize the default detour for the loaders */ + loader_detour(detour_create(metacall_detour())); + + if (metacall_link_trampoline == NULL) + { + /* Store the original symbol link function */ + metacall_link_trampoline = metacall_link_func(); + } + + if (metacall_link_table == NULL) + { + metacall_link_table = set_create(&hash_callback_str, &comparable_callback_str); + + if (metacall_link_table == NULL) + { + log_write("metacall", LOG_LEVEL_ERROR, "MetaCall failed to create link table"); + + metacall_link_destroy(); + + return 1; + } + } + + return 0; +} + +static int metacall_link_register_load_cb(detour d, detour_handle handle) +{ + void (*addr)(void) = NULL; + + return detour_replace(d, handle, metacall_link_func_name, (void (*)(void))(&metacall_link_hook), &addr); +} + +int metacall_link_register(const char *tag, const char *library, const char *symbol, void (*fn)(void)) +{ + void *ptr; + + if (metacall_link_table == NULL) + { + return 1; + } + + if (loader_hook(tag, library, metacall_link_register_load_cb) == NULL) + { + return 1; + } + + dynlink_symbol_uncast(fn, ptr); + + return set_insert(metacall_link_table, (set_key)symbol, ptr); +} + +int metacall_link_register_loader(void *loader, const char *library, const char *symbol, void (*fn)(void)) +{ + void *ptr; + + if (metacall_link_table == NULL) + { + return 1; + } + + if (loader_hook_impl(loader, library, metacall_link_register_load_cb) == NULL) + { + return 1; + } + + dynlink_symbol_uncast(fn, ptr); + + return set_insert(metacall_link_table, (set_key)symbol, ptr); +} + +int metacall_link_unregister(const char *tag, const char *library, const char *symbol) +{ + if (metacall_link_table == NULL) + { + return 1; + } + + if (set_get(metacall_link_table, (set_key)symbol) == NULL) + { + return 0; + } + + /* TODO: Restore the hook? We need support for this on the detour API */ + (void)tag; + (void)library; + + return (set_remove(metacall_link_table, (set_key)symbol) == NULL); +} + +void metacall_link_destroy(void) +{ + threading_mutex_lock(&link_mutex); + + if (metacall_link_table != NULL) + { + set_destroy(metacall_link_table); + + metacall_link_table = NULL; + } + + threading_mutex_unlock(&link_mutex); + + threading_mutex_destroy(&link_mutex); +} diff --git a/source/metacall/source/metacall_log.c b/source/metacall/source/metacall_log.c index 0678f738d3..c2acb82b05 100644 --- a/source/metacall/source/metacall_log.c +++ b/source/metacall/source/metacall_log.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/metacall/source/metacall_value.c b/source/metacall/source/metacall_value.c index b598e599bd..821b6bc250 100644 --- a/source/metacall/source/metacall_value.c +++ b/source/metacall/source/metacall_value.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugin/CMakeLists.txt b/source/plugin/CMakeLists.txt index 1682864041..871d222b38 100644 --- a/source/plugin/CMakeLists.txt +++ b/source/plugin/CMakeLists.txt @@ -163,7 +163,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/plugin/include/plugin/plugin.h b/source/plugin/include/plugin/plugin.h index 8f856a36f4..17464f042c 100644 --- a/source/plugin/include/plugin/plugin.h +++ b/source/plugin/include/plugin/plugin.h @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugin/include/plugin/plugin_descriptor.h b/source/plugin/include/plugin/plugin_descriptor.h index 47eb54fc82..770f081b1f 100644 --- a/source/plugin/include/plugin/plugin_descriptor.h +++ b/source/plugin/include/plugin/plugin_descriptor.h @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugin/include/plugin/plugin_impl.h b/source/plugin/include/plugin/plugin_impl.h index 3a0d108b2a..1489ca97d6 100644 --- a/source/plugin/include/plugin/plugin_impl.h +++ b/source/plugin/include/plugin/plugin_impl.h @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,8 +59,36 @@ PLUGIN_API void *plugin_iface(plugin p); PLUGIN_API void *plugin_impl(plugin p); -PLUGIN_API void plugin_destroy_delayed(plugin p); - +/** +* @brief +* Executes the destructor once and nullifies it, it does not free +* the memory of the plugin but the destructor is removed +* +* @param[in] p +* The plugin that will be used to execute the destructor +*/ +PLUGIN_API void plugin_destructor(plugin p); + +/** +* @brief +* Marks the plugin as destroyed, nullifies the destructor +* but does not free the memory of the plugin, this is useful +* for when we execute loader plugin manager in host mode, +* because the destructor is called without the control of metacall, +* and it prevents to call it again after it has been called by host +* +* @param[in] p +* The plugin that will be used to clear the destructor +*/ +PLUGIN_API void plugin_destroyed(plugin p); + +/** +* @brief +* Executes the destructor if any and frees all the memory +* +* @param[in] p +* The plugin to be destroyed +*/ PLUGIN_API void plugin_destroy(plugin p); #ifdef __cplusplus diff --git a/source/plugin/include/plugin/plugin_interface.hpp b/source/plugin/include/plugin/plugin_interface.hpp index c3719abfb6..8ec8177557 100644 --- a/source/plugin/include/plugin/plugin_interface.hpp +++ b/source/plugin/include/plugin/plugin_interface.hpp @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugin/include/plugin/plugin_loader.h b/source/plugin/include/plugin/plugin_loader.h index 2113010cbe..4862918616 100644 --- a/source/plugin/include/plugin/plugin_loader.h +++ b/source/plugin/include/plugin/plugin_loader.h @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugin/include/plugin/plugin_manager.h b/source/plugin/include/plugin/plugin_manager.h index 8698733b59..a4340bb597 100644 --- a/source/plugin/include/plugin/plugin_manager.h +++ b/source/plugin/include/plugin/plugin_manager.h @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ struct plugin_manager_type struct plugin_manager_interface_type { - int (*clear)(plugin_manager, plugin); /* Hook for clearing the plugin implementation */ + void (*clear)(plugin_manager, plugin); /* Hook for clearing the plugin implementation */ void (*destroy)(plugin_manager, void *); /* Hook for destroying the plugin manager implementation */ }; @@ -86,8 +86,6 @@ PLUGIN_API plugin plugin_manager_create(plugin_manager manager, const char *name PLUGIN_API plugin plugin_manager_get(plugin_manager manager, const char *name); -PLUGIN_API void plugin_manager_iterate(plugin_manager manager, int (*iterator)(plugin_manager, plugin, void *), void *data); - PLUGIN_API int plugin_manager_clear(plugin_manager manager, plugin p); PLUGIN_API void plugin_manager_destroy(plugin_manager manager); diff --git a/source/plugin/source/plugin.c b/source/plugin/source/plugin.c index 4089f2d026..b8b325cbc9 100644 --- a/source/plugin/source/plugin.c +++ b/source/plugin/source/plugin.c @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ const char *plugin_print_info(void) { static const char plugin_info[] = "Plugin Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef PLUGIN_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/plugin/source/plugin_descriptor.c b/source/plugin/source/plugin_descriptor.c index 491895e050..2a5ff1d12c 100644 --- a/source/plugin/source/plugin_descriptor.c +++ b/source/plugin/source/plugin_descriptor.c @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +65,7 @@ plugin_descriptor plugin_descriptor_create(char *path, char *library_name, char return NULL; } - descriptor->iface_singleton = (void *(*)(void))DYNLINK_SYMBOL_GET(address); + descriptor->iface_singleton = (void *(*)(void))(address); if (descriptor->iface_singleton == NULL) { diff --git a/source/plugin/source/plugin_impl.c b/source/plugin/source/plugin_impl.c index 785a55834d..511897bde7 100644 --- a/source/plugin/source/plugin_impl.c +++ b/source/plugin/source/plugin_impl.c @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -101,7 +101,7 @@ void *plugin_impl(plugin p) return p->impl; } -void plugin_destroy_delayed(plugin p) +void plugin_destructor(plugin p) { if (p != NULL) { @@ -113,6 +113,14 @@ void plugin_destroy_delayed(plugin p) } } +void plugin_destroyed(plugin p) +{ + if (p != NULL) + { + p->dtor = NULL; + } +} + void plugin_destroy(plugin p) { if (p != NULL) diff --git a/source/plugin/source/plugin_loader.c b/source/plugin/source/plugin_loader.c index 5212f7ebb5..7b3ff0774f 100644 --- a/source/plugin/source/plugin_loader.c +++ b/source/plugin/source/plugin_loader.c @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -178,20 +178,19 @@ char *plugin_loader_generate_library_name(const char *name, char *suffix) char *plugin_loader_generate_symbol_iface_name(const char *name, char *suffix) { size_t name_length = strlen(name); - size_t mangle_length = dynlink_symbol_name_mangle(name, name_length, NULL); size_t suffix_length = strlen(suffix); - char *symbol_iface_name = malloc(sizeof(char) * (mangle_length + suffix_length + 1)); + char *symbol_iface_name = malloc(sizeof(char) * (name_length + suffix_length + 1)); if (symbol_iface_name == NULL) { return NULL; } - dynlink_symbol_name_mangle(name, name_length, symbol_iface_name); + memcpy(symbol_iface_name, name, name_length); - memcpy(&symbol_iface_name[mangle_length], suffix, suffix_length); + memcpy(&symbol_iface_name[name_length], suffix, suffix_length); - symbol_iface_name[mangle_length + suffix_length] = '\0'; + symbol_iface_name[name_length + suffix_length] = '\0'; return symbol_iface_name; } diff --git a/source/plugin/source/plugin_manager.c b/source/plugin/source/plugin_manager.c index d3c06044b8..c2c78980ac 100644 --- a/source/plugin/source/plugin_manager.c +++ b/source/plugin/source/plugin_manager.c @@ -2,7 +2,7 @@ * Plugin Library by Parra Studios * A library for plugins at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,23 +31,12 @@ #include #if defined(WIN32) || defined(_WIN32) - #include + #include /* SetDllDirectoryA */ #endif -/* -- Declarations -- */ - -struct plugin_manager_iterate_cb_type -{ - plugin_manager manager; - int (*iterator)(plugin_manager, plugin, void *); - void *data; -}; - /* -- Private Methods -- */ static int plugin_manager_unregister(plugin_manager manager, plugin p); -static int plugin_manager_iterate_cb(set s, set_key key, set_value val, set_cb_iterate_args args); -static int plugin_manager_destroy_cb(set s, set_key key, set_value val, set_cb_iterate_args args); /* -- Methods -- */ @@ -105,13 +94,13 @@ int plugin_manager_initialize(plugin_manager manager, const char *name, const ch /* Initialize the library path */ if (manager->library_path == NULL) { - const char name[] = "metacall" + static const char library_name[] = "metacall" #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) - "d" + "d" #endif ; - dynlink_library_path_str path; + dynlink_path path; size_t length = 0; /* The order of precedence is: @@ -119,7 +108,7 @@ int plugin_manager_initialize(plugin_manager manager, const char *name, const ch * 2) Dynamic link library path of the host library * 3) Default compile time path */ - if (dynlink_library_path(name, path, &length) == 0) + if (dynlink_library_path(library_name, path, &length) == 0) { default_library_path = path; } @@ -138,16 +127,16 @@ int plugin_manager_initialize(plugin_manager manager, const char *name, const ch return 1; } - } - /* On Windows, pass the library path to the loader so it can find the dependencies of the plugins */ - /* For more information: https://github.com/metacall/core/issues/479 */ + /* On Windows, pass the library path to the loader so it can find the dependencies of the plugins */ + /* For more information: https://github.com/metacall/core/issues/479 */ #if defined(WIN32) || defined(_WIN32) - if (SetDllDirectoryA(manager->library_path) == FALSE) - { - log_write("metacall", LOG_LEVEL_ERROR, "Failed to register the DLL directory %s; plugins with other dependant DLLs may fail to load", manager->library_path); - } + if (SetDllDirectoryA(manager->library_path) == FALSE) + { + log_write("metacall", LOG_LEVEL_ERROR, "Failed to register the DLL directory %s; plugins with other dependant DLLs may fail to load", manager->library_path); + } #endif + } /* Initialize the plugin loader */ if (manager->l == NULL) @@ -234,36 +223,6 @@ plugin plugin_manager_get(plugin_manager manager, const char *name) return set_get(manager->plugins, (set_key)name); } -int plugin_manager_iterate_cb(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - - if (val != NULL && args != NULL) - { - struct plugin_manager_iterate_cb_type *args_ptr = (struct plugin_manager_iterate_cb_type *)args; - return args_ptr->iterator(args_ptr->manager, (plugin)val, args_ptr->data); - } - - return 0; -} - -void plugin_manager_iterate(plugin_manager manager, int (*iterator)(plugin_manager, plugin, void *), void *data) -{ - if (iterator == NULL) - { - return; - } - - struct plugin_manager_iterate_cb_type args = { - manager, - iterator, - data - }; - - set_iterate(manager->plugins, &plugin_manager_iterate_cb, (void *)&args); -} - int plugin_manager_unregister(plugin_manager manager, plugin p) { const char *name = plugin_name(p); @@ -299,35 +258,6 @@ int plugin_manager_clear(plugin_manager manager, plugin p) return result; } -int plugin_manager_destroy_cb(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - int result = 0; - - (void)s; - (void)key; - - if (val != NULL) - { - plugin p = (plugin)val; - - if (args != NULL) - { - plugin_manager manager = (plugin_manager)args; - - if (manager->iface != NULL && manager->iface->clear != NULL) - { - /* Call to the clear method of the manager */ - result = manager->iface->clear(manager, p); - } - } - - /* Unload the dynamic link library and destroy the plugin */ - plugin_destroy(p); - } - - return result; -} - void plugin_manager_destroy(plugin_manager manager) { /* If there's a destroy callback, probably the plugin manager needs a complex destroy algorithm */ @@ -340,7 +270,21 @@ void plugin_manager_destroy(plugin_manager manager) * plugin set and this will do nothing if the set has been emptied before with plugin_manager_clear */ if (manager->plugins != NULL) { - set_iterate(manager->plugins, &plugin_manager_destroy_cb, NULL); + struct set_iterator_type it; + + for (set_iterator_begin(&it, manager->plugins); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + plugin p = set_iterator_value(&it); + + if (manager->iface != NULL && manager->iface->clear != NULL) + { + /* Call to the clear method of the manager */ + manager->iface->clear(manager, p); + } + + /* Unload the dynamic link library and destroy the plugin */ + plugin_destroy(p); + } } /* Clear the name */ diff --git a/source/plugins/backtrace_plugin/CMakeLists.txt b/source/plugins/backtrace_plugin/CMakeLists.txt index e434b73030..089fa8539b 100644 --- a/source/plugins/backtrace_plugin/CMakeLists.txt +++ b/source/plugins/backtrace_plugin/CMakeLists.txt @@ -7,27 +7,28 @@ endif() # External dependencies # -include(FetchContent) +if(NOT (OPTION_BUILD_GUIX OR BackwardCpp_SOURCE)) + include(FetchContent) -FetchContent_Declare(BackwardCpp - GIT_REPOSITORY https://github.com/bombela/backward-cpp - GIT_TAG f30744bcf726ea3735df7ecf9e9de9ddac540283 -) + FetchContent_Declare(BackwardCpp + GIT_REPOSITORY https://github.com/metacall/backward-cpp + GIT_TAG 0bfd0a07a61551413ccd2ab9a9099af3bad40681 + ) -FetchContent_MakeAvailable(BackwardCpp) + FetchContent_MakeAvailable(BackwardCpp) -FetchContent_GetProperties(BackwardCpp - SOURCE_DIR BackwardCpp_SOURCE - POPULATED BackwardCpp_POPULATED -) + FetchContent_GetProperties(BackwardCpp + SOURCE_DIR BackwardCpp_SOURCE + POPULATED BackwardCpp_POPULATED + ) -if(NOT BackwardCpp_POPULATED) - FetchContent_Populate(backward-cpp) + if(NOT BackwardCpp_POPULATED) + FetchContent_Populate(BackwardCpp) + endif() endif() if(NOT BackwardCpp_POPULATED OR NOT BackwardCpp_SOURCE) message(STATUS "BackwardCpp could not be installed, trying to find it on the system") - return() endif() find_package(Backward @@ -158,8 +159,6 @@ target_include_directories(${target} $ # MetaCall includes - ${BACKWARD_INCLUDE_DIR} # Backward-cpp includes - PUBLIC ${DEFAULT_INCLUDE_DIRECTORIES} @@ -177,11 +176,11 @@ target_link_libraries(${target} PRIVATE ${META_PROJECT_NAME}::metacall # MetaCall library + Backward::Backward # Backward-cpp library + PUBLIC ${DEFAULT_LIBRARIES} - Backward::Backward # Backward-cpp library - INTERFACE ) @@ -216,7 +215,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h b/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h index 5269713f94..8277dc2e47 100644 --- a/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h +++ b/source/plugins/backtrace_plugin/include/backtrace_plugin/backtrace_plugin.h @@ -2,7 +2,7 @@ * Backtrace Plugin by Parra Studios * A plugin implementing backtracing functionality for MetaCall Core. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif BACKTRACE_PLUGIN_API int backtrace_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(backtrace_plugin); - #ifdef __cplusplus } #endif diff --git a/source/plugins/backtrace_plugin/source/backtrace_plugin.cpp b/source/plugins/backtrace_plugin/source/backtrace_plugin.cpp index c3e826fd33..16f8fe0ff3 100644 --- a/source/plugins/backtrace_plugin/source/backtrace_plugin.cpp +++ b/source/plugins/backtrace_plugin/source/backtrace_plugin.cpp @@ -2,7 +2,7 @@ * Backtrace Plugin by Parra Studios * A plugin implementing backtracing functionality for MetaCall Core. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/plugins/sandbox_plugin/CMakeLists.txt b/source/plugins/sandbox_plugin/CMakeLists.txt index 8d271bf3f6..e570a95283 100644 --- a/source/plugins/sandbox_plugin/CMakeLists.txt +++ b/source/plugins/sandbox_plugin/CMakeLists.txt @@ -196,7 +196,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/plugins/sandbox_plugin/cmake/FindLibSecComp.cmake b/source/plugins/sandbox_plugin/cmake/FindLibSecComp.cmake index 9293d405ef..8265541fa4 100644 --- a/source/plugins/sandbox_plugin/cmake/FindLibSecComp.cmake +++ b/source/plugins/sandbox_plugin/cmake/FindLibSecComp.cmake @@ -2,7 +2,7 @@ # CMake Find LibSecComp library by Parra Studios # CMake script to find SecComp library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h b/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h index 12d8c2caf4..1fc338afe5 100644 --- a/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h +++ b/source/plugins/sandbox_plugin/include/sandbox_plugin/sandbox_plugin.h @@ -2,7 +2,7 @@ * Sandbox Plugin by Parra Studios * A plugin implementing sandboxing functionality for MetaCall Core. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,16 +23,12 @@ #include -#include - #ifdef __cplusplus extern "C" { #endif SANDBOX_PLUGIN_API int sandbox_plugin(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(sandbox_plugin); - #ifdef __cplusplus } #endif diff --git a/source/plugins/sandbox_plugin/source/sandbox_plugin.cpp b/source/plugins/sandbox_plugin/source/sandbox_plugin.cpp index 06eed5fd97..48bd7a715a 100644 --- a/source/plugins/sandbox_plugin/source/sandbox_plugin.cpp +++ b/source/plugins/sandbox_plugin/source/sandbox_plugin.cpp @@ -2,7 +2,7 @@ * Sandbox Plugin by Parra Studios * A plugin implementing sandboxing functionality for MetaCall Core. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -378,7 +378,10 @@ void *sandbox_signals(size_t argc, void *args[], void *data) SCMP_SYS(sigsuspend), SCMP_SYS(sigreturn), SCMP_SYS(rt_sigaction), - SCMP_SYS(rt_sigprocmask), + /* TODO: For some reason this makes the metacall-sandbox-plugin-test fail, + disabled it for now, we should review it + */ + /* SCMP_SYS(rt_sigprocmask), */ SCMP_SYS(rt_sigpending), SCMP_SYS(rt_sigsuspend), SCMP_SYS(rt_sigreturn), diff --git a/source/portability/CMakeLists.txt b/source/portability/CMakeLists.txt index 17d2b2159b..1855258d28 100644 --- a/source/portability/CMakeLists.txt +++ b/source/portability/CMakeLists.txt @@ -35,16 +35,21 @@ set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(headers ${include_path}/portability.h ${include_path}/portability_assert.h - ${include_path}/portability_path.h + ${include_path}/portability_constructor.h ${include_path}/portability_executable_path.h ${include_path}/portability_library_path.h + ${include_path}/portability_working_path.h + ${include_path}/portability_path.h + ${include_path}/portability_atexit.h ) set(sources ${source_path}/portability.c - ${source_path}/portability_path.c ${source_path}/portability_executable_path.c ${source_path}/portability_library_path.c + ${source_path}/portability_working_path.c + ${source_path}/portability_path.c + ${source_path}/portability_atexit.c ) # Group source files @@ -153,7 +158,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/portability/include/portability/portability.h b/source/portability/include/portability/portability.h index 6316fda482..f440b5050e 100644 --- a/source/portability/include/portability/portability.h +++ b/source/portability/include/portability/portability.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ #include #include +#include #include #ifdef __cplusplus diff --git a/source/portability/include/portability/portability_assert.h b/source/portability/include/portability/portability_assert.h index bb90a39b5d..60e67d1221 100644 --- a/source/portability/include/portability/portability_assert.h +++ b/source/portability/include/portability/portability_assert.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/portability/include/portability/portability_atexit.h b/source/portability/include/portability/portability_atexit.h new file mode 100644 index 0000000000..dc1ad0356e --- /dev/null +++ b/source/portability/include/portability/portability_atexit.h @@ -0,0 +1,63 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 PORTABILITY_ATEXIT_H +#define PORTABILITY_ATEXIT_H 1 + +/* -- Headers -- */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Type Definitions -- */ + +typedef void (*portability_atexit_fn)(void); + +/* -- Methods -- */ + +/** +* @brief +* Initialize atexit instance for custom at exit handlers +* +* @return +* Zero if success, different from zero otherwise +*/ +PORTABILITY_API int portability_atexit_initialize(void); + +/** +* @brief +* Register handler to be run at exit +* +* @param[in] handler +* Function pointer to the handler that will be executed at exit +* +* @return +* Zero if success, different from zero otherwise +*/ +PORTABILITY_API int portability_atexit_register(portability_atexit_fn handler); + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_ATEXIT_H */ diff --git a/source/portability/include/portability/portability_compiler_detection.h b/source/portability/include/portability/portability_compiler.h similarity index 98% rename from source/portability/include/portability/portability_compiler_detection.h rename to source/portability/include/portability/portability_compiler.h index ec2e4eaaa3..3fa5481cc7 100644 --- a/source/portability/include/portability/portability_compiler_detection.h +++ b/source/portability/include/portability/portability_compiler.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,8 @@ * */ -#ifndef PORTABILITY_COMPILER_DETECTION_H -#define PORTABILITY_COMPILER_DETECTION_H 1 +#ifndef PORTABILITY_COMPILER_H +#define PORTABILITY_COMPILER_H 1 /* TODO: This needs to be implemented properly, including another file for architecture and operative system detection */ @@ -490,4 +490,4 @@ // PORTABILITY_THREAD_LOCAL not defined for this configuration. #endif -#endif /* PORTABILITY_COMPILER_DETECTION_H */ +#endif /* PORTABILITY_COMPILER_H */ diff --git a/source/portability/include/portability/portability_constructor.h b/source/portability/include/portability/portability_constructor.h new file mode 100644 index 0000000000..bb2879473d --- /dev/null +++ b/source/portability/include/portability/portability_constructor.h @@ -0,0 +1,79 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 PORTABILITY_CONSTRUCTOR_H +#define PORTABILITY_CONSTRUCTOR_H 1 + +/* -- Headers -- */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Headers -- */ + +#include + +#include +#include + +/* -- Macros -- */ + +#ifndef portability_constructor + + #ifdef __cplusplus + #define portability_constructor(ctor) \ + static void ctor(void); \ + static struct PREPROCESSOR_CONCAT(ctor, _type) \ + { \ + PREPROCESSOR_CONCAT(ctor, _type) \ + (void) \ + { \ + ctor(); \ + } \ + } PREPROCESSOR_CONCAT(ctor, _ctor); \ + static void ctor(void) + #elif defined(_MSC_VER) + /* TODO: Test MSVC version in release mode */ + #pragma section(".CRT$XCU", read) + #define portability_constructor_impl(ctor, prefix) \ + static void ctor(void); \ + __declspec(allocate(".CRT$XCU")) void (*PREPROCESSOR_CONCAT(ctor, _ptr))(void) = ctor; \ + __pragma(comment(linker, "/include:" prefix PREPROCESSOR_STRINGIFY(ctor) "_ptr")) static void ctor(void) + #ifdef _WIN64 + #define portability_constructor(ctor) portability_constructor_impl(ctor, "") + #else + #define portability_constructor(ctor) portability_constructor_impl(ctor, "_") + #endif + #else + #define portability_constructor(ctor) \ + static void ctor(void) __attribute__((constructor)); \ + static void ctor(void) + #endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_CONSTRUCTOR_H */ diff --git a/source/portability/include/portability/portability_executable_path.h b/source/portability/include/portability/portability_executable_path.h index 15494b0027..0813ef3d51 100644 --- a/source/portability/include/portability/portability_executable_path.h +++ b/source/portability/include/portability/portability_executable_path.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/portability/include/portability/portability_library_path.h b/source/portability/include/portability/portability_library_path.h index e31bd7d493..5daee5b8d0 100644 --- a/source/portability/include/portability/portability_library_path.h +++ b/source/portability/include/portability/portability_library_path.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +27,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /* -- Type Definitions -- */ typedef char portability_library_path_str[PORTABILITY_PATH_SIZE]; -#ifdef __cplusplus -extern "C" { -#endif +typedef int (*portability_library_path_list_cb)(const char *library, void *data); /* -- Methods -- */ @@ -53,7 +55,22 @@ extern "C" { * @return * Returns zero if it could find the path, different from zero if not found */ -PORTABILITY_API int portability_library_path(const char name[], portability_library_path_str path, size_t *length); +PORTABILITY_API int portability_library_path_find(const char name[], portability_library_path_str path, size_t *length); + +/** +* @brief +* List all the libraries loaded in the current process +* +* @param[in] callback +* Function pointer that will be called for each library loaded in the process +* +* @param[inout] data +* User defined data to pass to the callback +* +* @return +* Returns zero if it there is no error, different from zero on error +*/ +PORTABILITY_API int portability_library_path_list(portability_library_path_list_cb callback, void *data); #ifdef __cplusplus } diff --git a/source/portability/include/portability/portability_path.h b/source/portability/include/portability/portability_path.h index 5453c37ad7..38e743fbf4 100644 --- a/source/portability/include/portability/portability_path.h +++ b/source/portability/include/portability/portability_path.h @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,7 +109,58 @@ 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 null-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 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. + * + * @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); + +/** + * @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 null-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 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. + * + * @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/include/portability/portability_working_path.h b/source/portability/include/portability/portability_working_path.h new file mode 100644 index 0000000000..15c8d5af51 --- /dev/null +++ b/source/portability/include/portability/portability_working_path.h @@ -0,0 +1,54 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 PORTABILITY_WORKING_PATH_H +#define PORTABILITY_WORKING_PATH_H 1 + +/* -- Headers -- */ + +#include + +#include + +/* -- Type Definitions -- */ + +typedef char portability_working_path_str[PORTABILITY_PATH_SIZE]; + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) +typedef DWORD portability_working_path_length; +#else +typedef size_t portability_working_path_length; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Methods -- */ + +PORTABILITY_API int portability_working_path(portability_working_path_str path, portability_working_path_length *length); + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABILITY_WORKING_PATH_H */ diff --git a/source/portability/source/portability.c b/source/portability/source/portability.c index 7c57003ffa..4893aff52b 100644 --- a/source/portability/source/portability.c +++ b/source/portability/source/portability.c @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ const char *portability_print_info(void) { static const char portability_info[] = "Portability Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia \n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia \n" #ifdef PORTABILITY_STATIC_DEFINE "Compiled as static library type" diff --git a/source/portability/source/portability_atexit.c b/source/portability/source/portability_atexit.c new file mode 100644 index 0000000000..ee18e77959 --- /dev/null +++ b/source/portability/source/portability_atexit.c @@ -0,0 +1,140 @@ +/* + * MetaCall Library by Parra Studios + * A library for providing a foreign function interface calls. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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. + * + */ + +/* -- Headers -- */ + +#include + +#include + +/* -- Member Data -- */ + +struct atexit_node_type +{ + portability_atexit_fn handler; + struct atexit_node_type *next; +}; + +/* -- Private Variables -- */ + +static struct atexit_node_type *atexit_list = NULL; + +/* -- Private Methods -- */ + +static void portability_atexit_destroy(void) +{ + if (atexit_list != NULL) + { + do + { + struct atexit_node_type *prev = atexit_list; + + atexit_list = prev->next; + + if (prev->handler != NULL) + { + prev->handler(); + } + + free(prev); + + } while (atexit_list != NULL); + + atexit_list = NULL; + } +} + +/* -- Methods -- */ + +int portability_atexit_initialize(void) +{ + static int atexit_registered = 0; + + if (atexit_list == NULL) + { + atexit_list = malloc(sizeof(struct atexit_node_type)); + + if (atexit_list == NULL) + { + return 1; + } + + atexit_list->handler = NULL; + atexit_list->next = NULL; + } + + if (atexit_registered == 0) + { + atexit(&portability_atexit_destroy); + atexit_registered = 1; + } + + return 0; +} + +int portability_atexit_register(portability_atexit_fn handler) +{ + if (atexit_list == NULL) + { + return 1; + } + + if (atexit_list->handler == NULL) + { + atexit_list->handler = handler; + } + else + { + struct atexit_node_type *iterator = atexit_list; + + /* Find the last or duplicates */ + for (;;) + { + if (iterator->handler == handler) + { + /* Already registered, skip */ + return 1; + } + + if (iterator->next == NULL) + { + break; + } + + iterator = iterator->next; + } + + /* Allocate the new node */ + struct atexit_node_type *node = malloc(sizeof(struct atexit_node_type)); + + if (node == NULL) + { + return 1; + } + + node->handler = handler; + node->next = atexit_list; + + /* Insert it at the begining */ + atexit_list = node; + } + + return 0; +} diff --git a/source/portability/source/portability_executable_path.c b/source/portability/source/portability_executable_path.c index 7c63917d71..b5492bfc6d 100644 --- a/source/portability/source/portability_executable_path.c +++ b/source/portability/source/portability_executable_path.c @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/portability/source/portability_library_path.c b/source/portability/source/portability_library_path.c index a8b763cb29..cda5f9cb3e 100644 --- a/source/portability/source/portability_library_path.c +++ b/source/portability/source/portability_library_path.c @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,14 @@ #include +#include #include -#define PORTABILITY_LIBRARY_PATH_SIZE (sizeof(portability_library_path_str) / sizeof(char)) - static int portability_library_path_ends_with(const char path[], const char name[]); #if defined(unix) || defined(__unix__) || defined(__unix) || \ - defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) + defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ + defined(__FreeBSD__) #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -38,48 +38,20 @@ static int portability_library_path_ends_with(const char path[], const char name #include -struct phdr_callback_type -{ - const char *name; - char *path; - size_t length; -}; - -static int portability_library_path_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) -{ - struct phdr_callback_type *cb = (struct phdr_callback_type *)data; - - (void)size; - - if (portability_library_path_ends_with(info->dlpi_name, cb->name) == 0) - { - cb->length = strnlen(info->dlpi_name, PORTABILITY_LIBRARY_PATH_SIZE); - - if (cb->length >= PORTABILITY_LIBRARY_PATH_SIZE) - { - return 2; - } - - memcpy(cb->path, info->dlpi_name, sizeof(char) * (cb->length + 1)); - - return 1; - } +#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) - return 0; -} + #include #elif defined(WIN32) || defined(_WIN32) || \ defined(__CYGWIN__) || defined(__CYGWIN32__) || \ defined(__MINGW32__) || defined(__MINGW64__) #define WIN32_LEAN_AND_MEAN - #include #include + #include -#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) - - #include - +#else + #error "Unsupported platform for portability_library_path" #endif int portability_library_path_ends_with(const char path[], const char name[]) @@ -95,18 +67,74 @@ int portability_library_path_ends_with(const char path[], const char name[]) return !(name_length <= path_length && strncmp(path + path_length - name_length, name, name_length) == 0); } -int portability_library_path(const char name[], portability_library_path_str path, size_t *length) +#if defined(unix) || defined(__unix__) || defined(__unix) || \ + defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ + defined(__FreeBSD__) + +/* -- Type Definitions -- */ + +typedef struct portability_library_path_find_phdr_type *portability_library_path_find_phdr; +typedef struct portability_library_path_list_phdr_type *portability_library_path_list_phdr; + +/* -- Member Data -- */ + +struct portability_library_path_find_phdr_type +{ + const char *name; + char *path; + size_t length; +}; + +struct portability_library_path_list_phdr_type +{ + portability_library_path_list_cb callback; + void *data; +}; + +/* -- Private Methods -- */ + +static int portability_library_path_find_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) +{ + portability_library_path_find_phdr find_phdr = (portability_library_path_find_phdr)data; + + (void)size; + + if (portability_library_path_ends_with(info->dlpi_name, find_phdr->name) == 0) + { + find_phdr->length = strnlen(info->dlpi_name, PORTABILITY_PATH_SIZE); + + memcpy(find_phdr->path, info->dlpi_name, sizeof(char) * (find_phdr->length + 1)); + + return 1; + } + + return 0; +} + +static int portability_library_path_list_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) +{ + portability_library_path_list_phdr list_phdr = (portability_library_path_list_phdr)data; + + (void)size; + + return list_phdr->callback(info->dlpi_name, list_phdr->data); +} + +#endif + +int portability_library_path_find(const char name[], portability_library_path_str path, size_t *length) { #if defined(unix) || defined(__unix__) || defined(__unix) || \ - defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) + defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ + defined(__FreeBSD__) - struct phdr_callback_type data = { + struct portability_library_path_find_phdr_type data = { name, path, 0 }; - if (dl_iterate_phdr(&portability_library_path_phdr_callback, (void *)&data) != 1) + if (dl_iterate_phdr(&portability_library_path_find_phdr_callback, (void *)&data) != 1) { return 1; } @@ -124,21 +152,22 @@ int portability_library_path(const char name[], portability_library_path_str pat HMODULE handle_modules[1024]; HANDLE handle_process = GetCurrentProcess(); - DWORD cb_needed; + DWORD modules_size; - if (EnumProcessModules(handle_process, handle_modules, sizeof(handle_modules), &cb_needed)) + if (EnumProcessModules(handle_process, handle_modules, sizeof(handle_modules), &modules_size)) { - size_t iterator; + size_t iterator, size = modules_size / sizeof(HMODULE); - for (iterator = 0; iterator < (cb_needed / sizeof(HMODULE)); ++iterator) + /* Start from 1 so we avoid the executable itself */ + for (iterator = 1; iterator < size; ++iterator) { - if (GetModuleFileNameEx(handle_process, handle_modules[iterator], path, PORTABILITY_LIBRARY_PATH_SIZE)) + if (GetModuleFileNameEx(handle_process, handle_modules[iterator], path, PORTABILITY_PATH_SIZE)) { if (portability_library_path_ends_with(path, name) == 0) { if (length != NULL) { - *length = strnlen(path, PORTABILITY_LIBRARY_PATH_SIZE); + *length = strnlen(path, PORTABILITY_PATH_SIZE); } return 0; @@ -153,24 +182,26 @@ int portability_library_path(const char name[], portability_library_path_str pat static const char dylib_suffix[] = "dylib"; uint32_t image_index, size = _dyld_image_count(); - size_t name_length = strnlen(name, PORTABILITY_LIBRARY_PATH_SIZE); + size_t name_length = strnlen(name, PORTABILITY_PATH_SIZE); size_t name_dylib_length = name_length + 3; - if (portability_library_path_ends_with(name, "so") == 0 && name_dylib_length < PORTABILITY_LIBRARY_PATH_SIZE) + 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)); } - for (image_index = 0; image_index < size; ++image_index) + /* Start from 1 so we avoid the executable itself */ + for (image_index = 1; image_index < size; ++image_index) { const char *image_name = _dyld_get_image_name(image_index); if (portability_library_path_ends_with(image_name, path) == 0) { - size_t image_length = strnlen(image_name, PORTABILITY_LIBRARY_PATH_SIZE); + size_t image_length = strnlen(image_name, PORTABILITY_PATH_SIZE); - if (image_length >= PORTABILITY_LIBRARY_PATH_SIZE) + if (image_length >= PORTABILITY_PATH_SIZE) { return 1; } @@ -189,7 +220,71 @@ int portability_library_path(const char name[], portability_library_path_str pat return 1; #else - /* Not supported */ - return 1; + #error "Unsupported platform for portability_library_path" +#endif +} + +int portability_library_path_list(portability_library_path_list_cb callback, void *data) +{ + if (callback == NULL) + { + return 1; + } + +#if defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \ + defined(__FreeBSD__) + { + struct portability_library_path_list_phdr_type list_phdr = { + callback, + data + }; + + return dl_iterate_phdr(&portability_library_path_list_phdr_callback, (void *)&list_phdr); + } +#elif (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) + { + uint32_t iterator, size = _dyld_image_count(); + + /* Start from 1 so we avoid the executable itself */ + for (iterator = 1; iterator < size; ++iterator) + { + const char *image_name = _dyld_get_image_name(iterator); + + if (callback(image_name, data) != 0) + { + return 1; + } + } + + return 0; + } +#elif defined(WIN32) || defined(_WIN32) + { + HANDLE process = GetCurrentProcess(); + HMODULE modules[1024]; + DWORD modules_size; + + if (EnumProcessModules(process, modules, sizeof(modules), &modules_size)) + { + size_t iterator, size = modules_size / sizeof(HMODULE); + char module_name[MAX_PATH]; + + /* Start from 1 so we avoid the executable itself */ + for (iterator = 1; iterator < size; ++iterator) + { + if (GetModuleFileNameExA(process, modules[iterator], module_name, sizeof(module_name) / sizeof(char))) + { + if (callback(module_name, data) != 0) + { + return 1; + } + } + } + } + + return 0; + } +#else + #error "Unsupported platform for portability_library_path" #endif } diff --git a/source/portability/source/portability_path.c b/source/portability/source/portability_path.c index 3a1a02ac7c..207a9cf29a 100644 --- a/source/portability/source/portability_path.c +++ b/source/portability/source/portability_path.c @@ -2,7 +2,7 @@ * Portability Library by Parra Studios * A generic cross-platform portability utility. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,52 +25,136 @@ /* 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 portability_path_basename_offset(const char *const path, const size_t path_size) { - if (path == NULL || name == NULL) + size_t offset = path_size; + + while (offset > 0 && !PORTABILITY_PATH_SEPARATOR(path[offset - 1])) { - return 0; + --offset; } - size_t i, count, last; + return offset; +} - for (i = 0, count = 0, last = 0; path[i] != '\0' && i < path_size && count < name_size; ++i) - { - name[count++] = path[i]; +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 (PORTABILITY_PATH_SEPARATOR(path[i])) + if (path == NULL) + { + if (name == NULL || name_size == 0) { - count = 0; + return 0; } - else if (path[i] == '.') + + name[0] = '\0'; + + return 1; + } + + /* 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 */ + while (rightmost_dot != name_start && path[rightmost_dot - 1] == '.') + { + --rightmost_dot; + } + + length = rightmost_dot - name_start; + size = length + 1; + + /* Return required size */ + if (name == NULL || size > name_size) + { + return size; + } + + 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) { - if (i > 0 && path[i - 1] == '.') - { - last = 0; - count = 0; - } - else - { - if (count > 0) - { - last = count - 1; - } - else - { - last = 0; - } - } + return 0; } + + name[0] = '\0'; + + return 1; } - if (last == 0 && count > 1) + /* 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] != '.') { - last = count; + ++leftmost_dot; } - name[last] = '\0'; + /* No dots found, use whole name */ + if (leftmost_dot == path_size) + { + --leftmost_dot; + } - return last + 1; + /* Name starts with dot, use the following dot instead */ + if (leftmost_dot == name_start) + { + 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 > 0) + { + 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/portability/source/portability_working_path.c b/source/portability/source/portability_working_path.c new file mode 100644 index 0000000000..b571b6f0aa --- /dev/null +++ b/source/portability/source/portability_working_path.c @@ -0,0 +1,74 @@ +/* + * Portability Library by Parra Studios + * A generic cross-platform portability utility. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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 + +#include + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + #include +#else + #include +#endif + +int portability_working_path(portability_working_path_str path, portability_working_path_length *length) +{ + const portability_working_path_length path_max_length = PORTABILITY_PATH_SIZE; + + /* Reset the path */ + memset(path, 0, path_max_length); + +#if defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) || defined(__CYGWIN32__) || \ + defined(__MINGW32__) || defined(__MINGW64__) + *length = GetCurrentDirectory(0, NULL); + + if (*length == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } + + if (*length > path_max_length) + { + /* TODO: Handle error */ + return 1; + } + + if (GetCurrentDirectory(*length, path) == 0) + { + /* TODO: DWORD dw = GetLastError(); */ + return 1; + } +#else + if (getcwd(path, path_max_length) == NULL) + { + *length = 0; + /* TODO: Handle error */ + return 1; + } + + *length = strnlen(path, path_max_length); +#endif + + return 0; +} diff --git a/source/ports/CMakeLists.txt b/source/ports/CMakeLists.txt index c27949d5f4..cc73de928d 100644 --- a/source/ports/CMakeLists.txt +++ b/source/ports/CMakeLists.txt @@ -2,7 +2,7 @@ # MetaCall Ports by Parra Studios # A complete infrastructure for supporting multiple language bindings in MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -45,57 +45,21 @@ option(OPTION_BUILD_PORTS_TS "Build TypeScript port." OFF) option(OPTION_BUILD_PORTS_ZIG "Build Zig port." OFF) # -# Port languages (Standalone) +# Port languages # -add_subdirectory(cxx_port) -add_subdirectory(node_port) -add_subdirectory(py_port) -add_subdirectory(go_port) -add_subdirectory(rs_port) -add_subdirectory(zig_port) - -# -# External dependencies -# - -# SWIG (TODO: Remove SWIG) -find_package(SWIG) - -if(NOT SWIG_FOUND) - message(WARNING "Swig not found: disabling ports depending on swig") - return() -endif() - -include(${SWIG_USE_FILE}) - -# -# Set MetaCall inlcude directories for SWIG -# - -get_filename_component(CMAKE_PARENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CMAKE_PARENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) - -list(APPEND CMAKE_SWIG_FLAGS - "-I${CMAKE_PARENT_SOURCE_DIR}/metacall/include" - "-I${CMAKE_PARENT_BINARY_DIR}/metacall/include" -) - -# -# Port languages (Swig) -# - -# TODO: Swig must be completely removed eventually, -# new architecture needs ports and loaders unified so -# Swig is not needed anymore - add_subdirectory(cs_port) +add_subdirectory(cxx_port) add_subdirectory(d_port) -# add_subdirectory(go_port) # TODO: Integrate it with CMake properly and with Docker +add_subdirectory(go_port) add_subdirectory(java_port) add_subdirectory(js_port) add_subdirectory(lua_port) +add_subdirectory(node_port) add_subdirectory(php_port) add_subdirectory(pl_port) +add_subdirectory(py_port) add_subdirectory(r_port) add_subdirectory(rb_port) +add_subdirectory(rs_port) +add_subdirectory(zig_port) diff --git a/source/ports/cxx_port/CMakeLists.txt b/source/ports/cxx_port/CMakeLists.txt index 076fe1bf15..13657ce943 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,30 +34,29 @@ include(SecurityFlags) # Sources # -set(inline_path "${CMAKE_CURRENT_SOURCE_DIR}/inline/${target_name}") -set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target_name}") +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 ) +set(inline + ${include_path}/metacall.inl +) + set(sources ${source_path}/metacall.cpp ) # Group source files -set(inline_group "Inline Files") set(header_group "Header Files (API)") +set(inline_group "Inline Files") 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(${include_path} "\\\\.inl$" + ${inline_group} ${inlines}) source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" ${source_group} ${sources}) @@ -70,16 +66,16 @@ source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" # Build library add_library(${target} - ${inlines} ${sources} ${headers} + ${inline} ) # Create namespaced alias 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 +96,12 @@ 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 - ${CMAKE_CURRENT_SOURCE_DIR}/inline PUBLIC ${DEFAULT_INCLUDE_DIRECTORIES} @@ -116,15 +112,31 @@ target_include_directories(${target} $ ) +# +# Libraries +# + +target_link_libraries(${target} + PRIVATE + ${META_PROJECT_NAME}::metacall + + PUBLIC + ${DEFAULT_LIBRARIES} + + INTERFACE + ${META_PROJECT_NAME}::metacall +) + # # Compile definitions # target_compile_definitions(${target} PRIVATE + ${target_upper}_EXPORTS # Export API PUBLIC - $<$>:${target_name_upper}_STATIC_DEFINE> + $<$>:${target_upper}_STATIC_DEFINE> ${DEFAULT_COMPILE_DEFINITIONS} INTERFACE @@ -143,11 +155,20 @@ target_compile_options(${target} INTERFACE ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC @@ -160,67 +181,8 @@ target_link_libraries(${target} # 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} + ${CMAKE_CURRENT_SOURCE_DIR}/include/metacall 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 $ -# ) - -# # -# # 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 8e2a1ef66c..593b472ea7 100644 --- a/source/ports/cxx_port/include/metacall/metacall.hpp +++ b/source/ports/cxx_port/include/metacall/metacall.hpp @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,17 +23,568 @@ /* -- Headers -- */ -#include - +#include +#include +#include +#include #include +#include +#include namespace metacall { -template -METACALL_API int metacall(std::string name, Ts... ts); +#include + +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 value_ptr; + + explicit value_base(void *value_ptr, void (*destructor)(void *) = &metacall_value_destroy) : + value_ptr(value_ptr, destructor) {} + + static void noop_destructor(void *) {} +}; + +template +class value : public value_base +{ +public: + explicit value(const T &v, void (*destructor)(void *) = &metacall_value_destroy) : + value_base(create(v), destructor) + { + if (value_ptr == nullptr) + { + throw std::runtime_error("Failed to create MetaCall value"); + } + } + + explicit value(void *value_ptr, void (*destructor)(void *) = &value_base::noop_destructor) : + value_base(value_ptr, 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"); + } + + // 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::create(const bool &v) +{ + return metacall_value_create_bool(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_BOOL; +} + +template <> +inline bool value::to_value() const +{ + return metacall_value_to_bool(value_ptr.get()); +} + +template <> +inline void *value::create(const char &v) +{ + return metacall_value_create_char(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_CHAR; +} + +template <> +inline char value::to_value() const +{ + return metacall_value_to_char(value_ptr.get()); +} + +template <> +inline void *value::create(const short &v) +{ + return metacall_value_create_short(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_SHORT; +} + +template <> +inline short value::to_value() const +{ + return metacall_value_to_short(value_ptr.get()); +} + +template <> +inline void *value::create(const int &v) +{ + return metacall_value_create_int(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_INT; +} + +template <> +inline int value::to_value() const +{ + return metacall_value_to_int(value_ptr.get()); +} + +template <> +inline void *value::create(const long &v) +{ + return metacall_value_create_long(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_LONG; +} + +template <> +inline long value::to_value() const +{ + return metacall_value_to_long(value_ptr.get()); +} + +template <> +inline void *value::create(const float &v) +{ + return metacall_value_create_float(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_FLOAT; +} + +template <> +inline float value::to_value() const +{ + return metacall_value_to_float(value_ptr.get()); +} + +template <> +inline void *value::create(const double &v) +{ + return metacall_value_create_double(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_DOUBLE; +} + +template <> +inline double value::to_value() const +{ + return metacall_value_to_double(value_ptr.get()); +} + +template <> +inline void *value::create(const std::string &v) +{ + return metacall_value_create_string(v.c_str(), v.size()); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_STRING; +} + +template <> +inline std::string value::to_value() const +{ + return metacall_value_to_string(value_ptr.get()); +} + +template <> +inline void *value::create(const char *const &v) +{ + return metacall_value_create_string(v, std::strlen(v)); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_STRING; +} + +template <> +inline const char *value::to_value() const +{ + return metacall_value_to_string(value_ptr.get()); +} + +template <> +inline void *value>::create(const std::vector &v) +{ + return metacall_value_create_buffer(v.data(), v.size()); +} + +template <> +inline enum metacall_value_id value>::id() +{ + return METACALL_BUFFER; +} + +template <> +inline std::vector value>::to_value() const +{ + void *ptr = value_ptr.get(); + char *buffer = static_cast(metacall_value_to_buffer(ptr)); + std::vector buffer_vector(buffer, buffer + metacall_value_count(ptr)); + + return buffer_vector; +} + +template <> +inline void *value>::create(const std::vector &v) +{ + return metacall_value_create_buffer(v.data(), v.size()); +} + +template <> +inline enum metacall_value_id value>::id() +{ + return METACALL_BUFFER; +} + +template <> +inline std::vector value>::to_value() const +{ + void *ptr = value_ptr.get(); + unsigned char *buffer = static_cast(metacall_value_to_buffer(ptr)); + std::vector buffer_vector(buffer, buffer + metacall_value_count(ptr)); + + return buffer_vector; +} + +template <> +inline void *value::create(void *const &v) +{ + return metacall_value_create_ptr(v); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_PTR; +} + +template <> +inline void *value::to_value() const +{ + return metacall_value_to_ptr(value_ptr.get()); +} + +template <> +inline void *value::create(const std::nullptr_t &) +{ + return metacall_value_create_null(); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_NULL; +} + +template <> +inline std::nullptr_t value::to_value() const +{ + return nullptr; +} + +// TODO: Future, Function, Class, Object, Exception, Throwable... + +class value_ref +{ +public: + explicit value_ref(void *ptr) : + ptr(ptr) {} + + template + T as() const + { + return value(ptr).to_value(); + } + +private: + void *ptr; +}; + +class array : public value_base +{ +public: + template + explicit array(Args &&...args) : + value_base(create(std::forward(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 + T get(std::size_t index) const + { + void **array_ptr = to_value(); + + return value(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 + 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)...); + + return array_value; + } + + // Recursive unpacking using fold expression (C++17+) + template + 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>::create(std::forward(args))), + ...); + } +}; + +template <> +inline void *value::create(const array &v) +{ + return metacall_value_copy(v.to_raw()); +} + +template <> +inline enum metacall_value_id value::id() +{ + return METACALL_ARRAY; +} + +template <> +inline array value::to_value() const +{ + return array(to_raw()); +} + +template +class map : public value_base +{ +public: + using pair_type = std::pair; + using pair_value_type = std::pair, value>; + + map(std::initializer_list 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(pair.first, &value_base::noop_destructor), value(pair.second, &value_base::noop_destructor)); + + // 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(); + } + + 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(); + 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(tuple_array[0]), value(tuple_array[1])); + + // Store into the map + m.emplace(pair.first.to_value(), std::move(pair)); + } + } + +private: + std::unordered_map m; +}; + +namespace detail +{ +template +constexpr bool is_value_base = std::is_base_of_v>>; + +template +value_base to_value_base(T &&arg) +{ + if constexpr (is_value_base) + { + return std::move(arg); + } + else + { + return value>(std::forward(arg)); + } +} + +} /* namespace detail */ + +template +Ret metacall(std::string name, Args &&...args) +{ + constexpr std::size_t size = sizeof...(Args); + std::array value_args = { { detail::to_value_base(std::forward(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 result(ret, &metacall_value_destroy); + + return result.to_value(); +} } /* namespace metacall */ +// TODO: Move implementations to metacall.inl #include #endif /* METACALL_HPP */ diff --git a/source/ports/cxx_port/inline/metacall/metacall.inl b/source/ports/cxx_port/include/metacall/metacall.inl similarity index 76% rename from source/ports/cxx_port/inline/metacall/metacall.inl rename to source/ports/cxx_port/include/metacall/metacall.inl index 743c6a0c84..9a36cec3ab 100644 --- a/source/ports/cxx_port/inline/metacall/metacall.inl +++ b/source/ports/cxx_port/include/metacall/metacall.inl @@ -1,40 +1,30 @@ -/* - * Format Library by Parra Studios - * A cross-platform library for supporting formatted input / output. - * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia - * - * 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 - -#include - -namespace metacall -{ -template -METACALL_API int metacall(std::string name, Ts... ts) -{ - return 0; -} - -} /* namespace metacall */ - -#endif /* METACALL_INL */ +/* + * Format Library by Parra Studios + * A cross-platform library for supporting formatted input / output. + * + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia + * + * 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/ports/cxx_port/source/metacall.cpp b/source/ports/cxx_port/source/metacall.cpp index d1a7cbe8f9..80f7ea357f 100644 --- a/source/ports/cxx_port/source/metacall.cpp +++ b/source/ports/cxx_port/source/metacall.cpp @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting formatted input / output. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/go_port/source/await.go b/source/ports/go_port/source/await.go index 11661b2dcf..2f1ecea86b 100644 --- a/source/ports/go_port/source/await.go +++ b/source/ports/go_port/source/await.go @@ -2,7 +2,7 @@ * MetaCall Go Port by Parra Studios * A frontend for Go language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/go_port/source/go_port.go b/source/ports/go_port/source/go_port.go index 4a7e125745..21692582a6 100644 --- a/source/ports/go_port/source/go_port.go +++ b/source/ports/go_port/source/go_port.go @@ -2,7 +2,7 @@ * MetaCall Go Port by Parra Studios * A frontend for Go language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/go_port/source/pointer.go b/source/ports/go_port/source/pointer.go index 5317378ecf..6bbac8dbf8 100644 --- a/source/ports/go_port/source/pointer.go +++ b/source/ports/go_port/source/pointer.go @@ -2,7 +2,7 @@ * MetaCall Go Port by Parra Studios * A frontend for Go language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/java_port/CMakeLists.txt b/source/ports/java_port/CMakeLists.txt index 86a5862ae0..6f14b448b4 100644 --- a/source/ports/java_port/CMakeLists.txt +++ b/source/ports/java_port/CMakeLists.txt @@ -44,265 +44,3 @@ message(STATUS "Port ${target}") # https://cmake.org/cmake/help/latest/module/UseJava.html # https://searchcode.com/codesearch/view/7927641/ # https://github.com/Kurento/kms-core/blob/master/CMake/FindMaven.cmake - -# # Set API export file and macro -# string(TOUPPER ${target} target_upper) -# set(export_file "include/${target}/${target}_api.h") -# set(export_macro "${target_upper}_API") - -# # -# # Sources -# # - -# set(interface_path "${CMAKE_CURRENT_SOURCE_DIR}/interface/${target}") -# set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") -# set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") - -# set(interfaces -# ${interface_path}/java_port.i -# ) - -# set(headers -# ${include_path}/java_port.h -# ) - -# set(sources -# ${source_path}/java_port.c -# ) - -# # Group source files -# set(interface_group "Interface Files (SWIG)") -# set(header_group "Header Files (API)") -# set(source_group "Source Files") -# source_group_by_path(${interface_path} "\\\\.i$" -# ${interface_group} ${interfaces}) -# source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" -# ${header_group} ${headers}) -# source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" -# ${source_group} ${sources}) - -# # -# # SWIG Configuration -# # - -# # Set SWIG flags -# if(CMAKE_BUILD_TYPE STREQUAL "Debug") -# list(APPEND CMAKE_SWIG_FLAGS "-DDEBUG") -# else() -# list(APPEND CMAKE_SWIG_FLAGS "-DNDEBUG") -# endif() - -# # Set SWIG include path -# include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") -# include_directories("${CMAKE_CURRENT_SOURCE_DIR}/interface") - -# # -# # Create library -# # - -# foreach(file ${interfaces} ${headers} ${sources}) -# set_source_files_properties( -# ${file} -# PROPERTY SWIG_FLAGS "-java" "-includeall" -# ) - -# set_source_files_properties( -# ${file} -# PROPERTIES CPLUSPLUS OFF -# ) -# endforeach() - -# if(${CMAKE_VERSION} VERSION_LESS "3.8.0") -# swig_add_module(${target} -# java -# ${interfaces} -# ${headers} -# ${sources} -# ) -# else() -# swig_add_library(${target} -# LANGUAGE java -# SOURCES ${interfaces} ${headers} ${sources} -# ) -# endif() - -# # -# # Dependecies -# # - -# add_dependencies(${SWIG_MODULE_${target}_REAL_NAME} -# ${META_PROJECT_NAME}::metacall -# ) - -# # Create namespaced alias -# add_library(${META_PROJECT_NAME}::${target} ALIAS ${SWIG_MODULE_${target}_REAL_NAME}) - -# # Export library for downstream projects -# export(TARGETS ${SWIG_MODULE_${target}_REAL_NAME} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake) - -# # Create API export header -# generate_export_header(${SWIG_MODULE_${target}_REAL_NAME} -# EXPORT_FILE_NAME ${export_file} -# EXPORT_MACRO_NAME ${export_macro} -# ) - -# # -# # Project options -# # - -# set_target_properties(${SWIG_MODULE_${target}_REAL_NAME} -# PROPERTIES -# ${DEFAULT_PROJECT_OPTIONS} -# FOLDER "${IDE_FOLDER}" -# ) - -# # -# # Include directories -# # -# target_include_directories(${SWIG_MODULE_${target}_REAL_NAME} -# PRIVATE -# ${PROJECT_BINARY_DIR}/source/include -# ${CMAKE_CURRENT_SOURCE_DIR}/include -# ${CMAKE_CURRENT_BINARY_DIR}/include - -# $ # MetaCall includes -# ${JAVA_INCLUDE_DIRS} # Java includes -# ${JNI_INCLUDE_DIRS} # JNI includes - -# PUBLIC -# ${DEFAULT_INCLUDE_DIRECTORIES} - -# INTERFACE -# $ -# $ -# $ -# ) - -# # -# # Libraries -# # - -# swig_link_libraries(${target} -# PRIVATE -# ${JAVA_LIBRARY} # Java libraries -# ${JNI_LIBRARIES} # JNI libraries - -# ${META_PROJECT_NAME}::metacall - -# PUBLIC -# ${DEFAULT_LIBRARIES} - -# INTERFACE -# ) - -# # -# # Compile definitions -# # - -# target_compile_definitions(${SWIG_MODULE_${target}_REAL_NAME} -# PRIVATE - -# PUBLIC -# $<$>:${target_upper}_STATIC_DEFINE> -# ${DEFAULT_COMPILE_DEFINITIONS} - -# INTERFACE -# ) - -# # -# # Compile options -# # - -# target_compile_options(${SWIG_MODULE_${target}_REAL_NAME} -# PRIVATE - -# PUBLIC -# ${DEFAULT_COMPILE_OPTIONS} - -# INTERFACE -# ) - -# # -# # Linker options -# # - -# target_link_libraries(${SWIG_MODULE_${target}_REAL_NAME} -# PRIVATE -# ${META_PROJECT_NAME}::metacall - -# PUBLIC -# ${DEFAULT_LINKER_OPTIONS} - -# INTERFACE -# ) - -# # -# # Deployment -# # - -# # Library -# install(TARGETS ${SWIG_MODULE_${target}_REAL_NAME} -# EXPORT "${target}-export" COMPONENT dev -# RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT runtime -# LIBRARY DESTINATION ${INSTALL_SHARED} COMPONENT runtime -# ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT dev -# ) - -# # Header files -# install(DIRECTORY -# ${CMAKE_CURRENT_SOURCE_DIR}/include/${target} DESTINATION ${INSTALL_INCLUDE} -# COMPONENT dev -# ) - -# # Generated header files -# install(DIRECTORY -# ${CMAKE_CURRENT_BINARY_DIR}/include/${target} DESTINATION ${INSTALL_INCLUDE} -# COMPONENT dev -# ) - -# # CMake config -# install(EXPORT ${target}-export -# NAMESPACE ${META_PROJECT_NAME}:: -# DESTINATION ${INSTALL_CMAKE}/${target} -# COMPONENT dev -# ) - -# # -# # Configure test -# # - -# set(java_port_test "${target}_test") -# set(java_port_test_path "${PROJECT_OUTPUT_DIR}/${java_port_test}.java") - -# # Require module name -# if(CMAKE_BUILD_TYPE STREQUAL "Debug") -# get_target_property(DEBUG_POSTFIX ${SWIG_MODULE_${target}_REAL_NAME} "DEBUG_POSTFIX") -# set(JAVA_PORT_NAME "${SWIG_MODULE_${target}_REAL_NAME}${DEBUG_POSTFIX}") -# else() -# set(JAVA_PORT_NAME "${SWIG_MODULE_${target}_REAL_NAME}") -# endif() - -# configure_file(test/run.java.in ${java_port_test_path}) - -# # -# # Define test -# # - -# add_test(NAME ${target} -# COMMAND ${JAVA_EXECUTABLE} ${java_port_test_path} -# ) - -# # -# # Define test labels -# # - -# set_property(TEST ${target} -# PROPERTY LABELS ${java_port_test} -# ) - -# include(TestEnvironmentVariables) - -# test_environment_variables(${target} -# "" -# ${TESTS_ENVIRONMENT_VARIABLES} -# ) diff --git a/source/ports/java_port/pom.xml b/source/ports/java_port/pom.xml deleted file mode 100644 index 71519cfdf2..0000000000 --- a/source/ports/java_port/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - 4.0.0 - - metacall - metacall-jna-java-port - 1.0-SNAPSHOT - - jnajavaport - - - UTF-8 - 1.7 - 1.7 - - - -Onkar Dahale -dahaleonkar@gmail.com - - - - - - junit - junit - 4.13.1 - test - - - net.java.dev.jna - jna - 5.9.0 - - - - - - - - - maven-clean-plugin - 3.1.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - - diff --git a/source/ports/java_port/src/main/java/metacall/Bindings.java b/source/ports/java_port/src/main/java/metacall/Bindings.java index b1de4d1c4a..71b93a7299 100644 --- a/source/ports/java_port/src/main/java/metacall/Bindings.java +++ b/source/ports/java_port/src/main/java/metacall/Bindings.java @@ -31,7 +31,7 @@ public interface Bindings extends Library SizeT metacall_function_size(Pointer func); int metacall_function_async(Pointer func); - int metacall_destroy(); + void metacall_destroy(); //metacall_value.h Pointer metacall_value_create_int(int i); diff --git a/source/ports/java_port/src/main/java/metacall/util.java b/source/ports/java_port/src/main/java/metacall/Utils.java similarity index 98% rename from source/ports/java_port/src/main/java/metacall/util.java rename to source/ports/java_port/src/main/java/metacall/Utils.java index 93a8cf55f0..70c1f2cadb 100644 --- a/source/ports/java_port/src/main/java/metacall/util.java +++ b/source/ports/java_port/src/main/java/metacall/Utils.java @@ -2,7 +2,7 @@ import com.sun.jna.*; -class util +class Utils { public static class SizeT extends IntegerType diff --git a/source/ports/java_port/test/run.java.in b/source/ports/java_port/test/main.java similarity index 100% rename from source/ports/java_port/test/run.java.in rename to source/ports/java_port/test/main.java diff --git a/source/ports/js_port/CMakeLists.txt b/source/ports/js_port/CMakeLists.txt index bae7efb737..7b2146e47f 100644 --- a/source/ports/js_port/CMakeLists.txt +++ b/source/ports/js_port/CMakeLists.txt @@ -7,6 +7,7 @@ endif() # External dependencies # +# V8 find_package(V8 5.1) if(NOT V8_FOUND) @@ -14,6 +15,21 @@ if(NOT V8_FOUND) return() endif() +# SWIG +find_package(SWIG) + +if(NOT SWIG_FOUND) + message(WARNING "Swig not found: disabling ports depending on swig") + return() +endif() + +include(${SWIG_USE_FILE}) + +list(APPEND CMAKE_SWIG_FLAGS + "-I${CMAKE_SOURCE_DIR}/source/metacall/include" + "-I${CMAKE_BINARY_DIR}/source/metacall/include" +) + # # Port name and options # @@ -213,11 +229,8 @@ target_compile_options(${SWIG_MODULE_${target}_REAL_NAME} # Linker options # -target_link_libraries(${SWIG_MODULE_${target}_REAL_NAME} +target_link_options(${SWIG_MODULE_${target}_REAL_NAME} PRIVATE - ${V8_LIBRARIES} # V8 libraries - - ${META_PROJECT_NAME}::metacall PUBLIC ${DEFAULT_LINKER_OPTIONS} @@ -383,7 +396,7 @@ target_compile_options(${js_port_test} # Linker options # -target_link_libraries(${js_port_test} +target_link_options(${js_port_test} PRIVATE PUBLIC diff --git a/source/ports/js_port/include/js_port/js_port.h b/source/ports/js_port/include/js_port/js_port.h index 245d537f15..20b6be901a 100644 --- a/source/ports/js_port/include/js_port/js_port.h +++ b/source/ports/js_port/include/js_port/js_port.h @@ -2,7 +2,7 @@ * MetaCall SWIG Wrapper by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/js_port/interface/js_port/js_port.i b/source/ports/js_port/interface/js_port/js_port.i index be171c7100..bb6a9e17b6 100644 --- a/source/ports/js_port/interface/js_port/js_port.i +++ b/source/ports/js_port/interface/js_port/js_port.i @@ -2,7 +2,7 @@ * MetaCall SWIG Wrapper by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/js_port/interface/js_port/js_port_impl.i b/source/ports/js_port/interface/js_port/js_port_impl.i index 711d560a49..994d689238 100644 --- a/source/ports/js_port/interface/js_port/js_port_impl.i +++ b/source/ports/js_port/interface/js_port/js_port_impl.i @@ -2,7 +2,7 @@ * MetaCall SWIG Wrapper by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/js_port/source/js_port.c b/source/ports/js_port/source/js_port.c index a2a304400f..3ac626eede 100644 --- a/source/ports/js_port/source/js_port.c +++ b/source/ports/js_port/source/js_port.c @@ -2,7 +2,7 @@ * MetaCall SWIG Wrapper by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/js_port/test/main.cpp b/source/ports/js_port/test/main.cpp index ea4d06e988..5338c28295 100644 --- a/source/ports/js_port/test/main.cpp +++ b/source/ports/js_port/test/main.cpp @@ -2,7 +2,7 @@ * MetaCall SWIG Wrapper by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/nim_port/LICENSE b/source/ports/nim_port/LICENSE index 2e591e57ad..d56ad81fad 100644 --- a/source/ports/nim_port/LICENSE +++ b/source/ports/nim_port/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2016-2024 Vicente Eduardo Ferrer Garcia + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/source/ports/node_port/CMakeLists.txt b/source/ports/node_port/CMakeLists.txt index 2402d2a7f6..1a04fc77e8 100644 --- a/source/ports/node_port/CMakeLists.txt +++ b/source/ports/node_port/CMakeLists.txt @@ -89,16 +89,10 @@ install(FILES # # Check if loaders are enabled -if(NOT OPTION_BUILD_CLI OR NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_LOADERS_TS OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB OR NOT OPTION_BUILD_SCRIPTS_TS) +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_LOADERS_TS OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB OR NOT OPTION_BUILD_SCRIPTS_TS) return() endif() -set(node_port_test "${target}_test") - -# -# Define test -# - if(OPTION_BUILD_THREAD_SANITIZER AND OPTION_BUILD_LOADERS_CS) # TODO: This test fails when run with thread sanitizer: # @@ -121,23 +115,10 @@ if(OPTION_BUILD_THREAD_SANITIZER AND OPTION_BUILD_LOADERS_CS) return() endif() -add_test(NAME ${target} - COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$" -D "INPUT=${CMAKE_CURRENT_SOURCE_DIR}/test/commands/node_port.txt" -P "${CMAKE_SOURCE_DIR}/source/cli/metacallcli/test/commands/command_runner.cmake" - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) - # -# Define test labels +# Define environment variables # -set_property(TEST ${target} - PROPERTY LABELS ${node_port_test} -) - -set_tests_properties(${target} PROPERTIES - PASS_REGULAR_EXPRESSION "Tests passed without errors" -) - include(TestEnvironmentVariables) # Enable cobol test if it is built @@ -158,19 +139,7 @@ if(OPTION_BUILD_LOADERS_RS) set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1") endif() -# Add dependencies and optional dependencies -add_dependencies(${target} - node_loader - mock_loader - py_loader - rb_loader - ts_loader - ${COBOL_DEPENDENCY} - ${C_DEPENDENCY} - ${RS_DEPENDENCY} -) - -# Disable OpenSSL related tests if versions are incompatible +# Disable OpenSSL related tests if versions are incompatible (TODO: Review this bug and remove the workaround if possible) set(NodeJS_EXECUTABLE_ONLY ON) find_package(NodeJS) @@ -205,11 +174,98 @@ if(NodeJS_FOUND AND Python_Interpreter_FOUND) endif() endif() -test_environment_variables(${target} +# +# Test importing NodeJS Port from CLI +# + +set(node_port_test "${target}_test") + +if(OPTION_BUILD_CLI) + message(STATUS "Test ${node_port_test}") + + add_test(NAME ${target} + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/test.js + ) + + # + # Define test labels + # + + set_property(TEST ${target} + PROPERTY LABELS ${node_port_test} + ) + + # Add dependencies and optional dependencies + add_dependencies(${target} + node_loader + mock_loader + py_loader + rb_loader + ts_loader + ${COBOL_DEPENDENCY} + ${C_DEPENDENCY} + ${RS_DEPENDENCY} + ) + + # Environment variables + test_environment_variables(${target} + "" + ${TESTS_ENVIRONMENT_VARIABLES} + ${TESTS_ENVIRONMENT_VARIABLES_COB} + ${TESTS_ENVIRONMENT_VARIABLES_C} + ${TESTS_ENVIRONMENT_VARIABLES_RS} + ${TESTS_ENVIRONMENT_VARIABLES_OPENSSL} + ) +endif() + +# +# Test importing NodeJS Port from node.exe +# + +set(node_port_test_exec "${node_port_test}_executable") + +# TODO: Since MacOS 14 with ARM64, it does not support well NodeJS executable with preloaded sanitizers +# The NodeJS initalization fails with: Node Loader failed to hook napi_register_module_v1 +if(APPLE) + # Check if NodeJS is compiled with Address Sanitizer + if(OPTION_BUILD_ADDRESS_SANITIZER) + check_asan_executable("${NodeJS_EXECUTABLE}" NodeJS_ASAN) + if(NOT NodeJS_ASAN) + # Skip this test because it gives false positives if NodeJS is not compiled with ASan + return() + endif() + endif() + + # Check if NodeJS is compiled with Thread Sanitizer + if(OPTION_BUILD_THREAD_SANITIZER) + check_tsan_executable("${NodeJS_EXECUTABLE}" NodeJS_TSAN) + if(NOT NodeJS_TSAN) + # Skip this test because it gives false positives if NodeJS is not compiled with TSan + return() + endif() + endif() +endif() + +message(STATUS "Test ${node_port_test_exec}") + +add_test(NAME ${node_port_test_exec} + COMMAND ${NodeJS_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test.js" +) + +# Define test labels +set_property(TEST ${node_port_test_exec} + PROPERTY LABELS ${node_port_test_exec} +) + +# Environment variables +test_environment_variables(${node_port_test_exec} "" ${TESTS_ENVIRONMENT_VARIABLES} ${TESTS_ENVIRONMENT_VARIABLES_COB} ${TESTS_ENVIRONMENT_VARIABLES_C} ${TESTS_ENVIRONMENT_VARIABLES_RS} ${TESTS_ENVIRONMENT_VARIABLES_OPENSSL} + "METACALL_INSTALL_PATH=${PROJECT_OUTPUT_DIR}" + ${TESTS_SANITIZER_ENVIRONMENT_VARIABLES} + ${TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES} ) diff --git a/source/ports/node_port/LICENSE b/source/ports/node_port/LICENSE index 2e591e57ad..d56ad81fad 100644 --- a/source/ports/node_port/LICENSE +++ b/source/ports/node_port/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2016-2024 Vicente Eduardo Ferrer Garcia + Copyright 2016-2025 Vicente Eduardo Ferrer Garcia Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/source/ports/node_port/index.d.ts b/source/ports/node_port/index.d.ts index 7b1d6d1bd2..e9fe6b2a2c 100644 --- a/source/ports/node_port/index.d.ts +++ b/source/ports/node_port/index.d.ts @@ -1,13 +1,26 @@ -declare module 'metacall' { - export function metacall(name: string, ...args: any): any; - export function metacallfms(name: string, buffer: string): any; - export function metacall_load_from_file(tag: string, paths: string[]): number; - export function metacall_load_from_file_export(tag: string, paths: string[]): any; - export function metacall_load_from_memory(tag: string, code: string): number; - export function metacall_load_from_memory_export(tag: string, code: string): any; - export function metacall_load_from_configuration(path: string): number; - export function metacall_load_from_configuration_export(path: string): any; - export function metacall_inspect(): any; - export function metacall_handle(tag: string, name: string): any; - export function metacall_logs(): void; +declare module "metacall" { + export function metacall(name: string, ...args: any): any; + export function metacallfms(name: string, buffer: string): any; + export function metacall_await(name: string, ...args: any): any; + export function metacall_execution_path(tag: string, path: string): number; + export function metacall_load_from_file(tag: string, paths: string[]): number; + export function metacall_load_from_file_export( + tag: string, + paths: string[] + ): any; + export function metacall_load_from_memory(tag: string, code: string): number; + export function metacall_load_from_memory_export( + tag: string, + code: string + ): any; + export function metacall_load_from_package(tag: string, pkg: string): number; + export function metacall_load_from_package_export( + tag: string, + pkg: string + ): any; + export function metacall_load_from_configuration(path: string): number; + export function metacall_load_from_configuration_export(path: string): any; + export function metacall_inspect(): any; // TODO: Implement return type + export function metacall_handle(tag: string, name: string): any; + export function metacall_logs(): void; } diff --git a/source/ports/node_port/index.js b/source/ports/node_port/index.js index 8d690b6d84..23ff5d6830 100644 --- a/source/ports/node_port/index.js +++ b/source/ports/node_port/index.js @@ -2,7 +2,7 @@ * MetaCall NodeJS Port by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,55 +22,139 @@ const mod = require('module'); const path = require('path'); +const fs = require('fs'); const { URL } = require('url'); /* TODO: RPC Loader */ +const findFilesRecursively = (directory, filePattern, depthLimit = Infinity) => { + const stack = [{ dir: directory, depth: 0 }]; + const files = []; + const fileRegex = new RegExp(filePattern); + + while (stack.length > 0) { + const { dir, depth } = stack.pop(); + + try { + if (depth > depthLimit) { + continue; + } + + const items = (() => { + try { + return fs.readdirSync(dir); + } catch (e) { + return []; + } + })(); + + for (const item of items) { + const fullPath = path.join(dir, item); + const stat = fs.statSync(fullPath); + + if (stat.isDirectory()) { + stack.push({ dir: fullPath, depth: depth + 1 }); + } else if (stat.isFile() && fileRegex.test(item)) { + files.push(fullPath); + } + } + } catch (err) { + console.error(`Error reading directory '${dir}' while searching for MetaCall Library:`, err); + } + } + + return files; +}; + +const platformInstallPaths = () => { + switch (process.platform) { + case 'win32': + return { + paths: [ path.join(process.env['LOCALAPPDATA'], 'MetaCall', 'metacall') ], + name: 'metacall.dll' + } + case 'darwin': + return { + paths: [ '/opt/homebrew/lib/', '/usr/local/lib/' ], + name: 'libmetacall.dylib' + } + case 'linux': + return { + paths: [ '/usr/local/lib/', '/gnu/lib/' ], + name: 'libmetacall.so' + } + } + + throw new Error(`Platform ${process.platform} not supported`) +}; + +const searchPaths = () => { + const customPath = process.env['METACALL_INSTALL_PATH']; + + if (customPath) { + return { + paths: [ customPath ], + name: /^(lib)?metacall(d)?\.(so|dylib|dll)$/ + } + } + + return platformInstallPaths() +}; + +const findLibrary = () => { + const searchData = searchPaths(); + + for (const p of searchData.paths) { + const files = findFilesRecursively(p, searchData.name, 0); + + if (files.length !== 0) { + return files[0]; + } + } + + throw new Error('MetaCall library not found, if you have it in a special folder, define it through METACALL_INSTALL_PATH') +}; + const addon = (() => { try { - /* This forces metacall port to be run always by metacall cli */ + /* If the binding can be loaded, it means MetaCall is being + * imported from the node_loader, in that case the runtime + * was initialized by node_loader itself and we can proceed. + */ return process._linkedBinding('node_loader_port_module'); } catch (e) { - console.error('MetaCall failed to load, probably you are importing this file from NodeJS directly.'); - console.error('You should use MetaCall CLI instead. Install it from: https://github.com/metacall/install'); - throw e; - - /* TODO: Until we find a better way to do this, we should disable it */ - /* - const write = (data, cb) => { - if (!process.stdout.write(data)) { - process.stdout.once('drain', cb); - } else { - process.nextTick(cb); - } - }; + /* If the port cannot be found, it means MetaCall port has + * been imported for the first time from node.exe, the + * runtime in this case has been initialized by node.exe, + * and MetaCall is not initialized + */ + process.env['METACALL_HOST'] = 'node'; - // Notify synchronously that we are launching MetaCall - write('NodeJS detected, launching MetaCall...\n', () => { - try { - const { spawnSync } = require('child_process'); - const args = [...process.argv]; + try { + const library = findLibrary(); - args.shift(); + const { constants } = require('os'); + const m = { exports: {} }; - const result = spawnSync('metacall', args, {}); + process.dlopen(m, library, constants.dlopen.RTLD_GLOBAL | constants.dlopen.RTLD_NOW); - if (result.error && result.error.code === 'ENOENT') { - write('MetaCall not found. Please install MetaCall from: https://github.com/metacall/install and run it again.\n', () => { - process.exit(1); - }); - } + /* Save argv */ + const argv = process.argv; + process.argv = []; - process.exit(result.status !== null ? result.status : 1); - } catch (e) { - const message = 'MetaCall failed to load, probably you are importing this file from NodeJS directly.\n' - + e.message + '\n' - + 'Install MetaCall from: https://github.com/metacall/install and run it again.\n'; + /* Pass the require function in order to import bootstrap.js and register it */ + const args = m.exports.register_bootstrap_startup(); - write(message, () => { - throw e; - }); - } - }); - */ + const bootstrap = require(args[0]); + + bootstrap(args[1], args[2], args[3]); + + /* Restore argv */ + process.argv = argv; + + return m.exports; + } catch (err) { + console.log(err); + process.exit(1); + } } })(); @@ -102,6 +186,18 @@ const metacall_await = (name, ...args) => { return addon.metacall_await(name, ...args); }; +const metacall_execution_path = (tag, path) => { + if (Object.prototype.toString.call(tag) !== '[object String]') { + throw Error('Tag should be a string indicating the id of the loader to be used [py, rb, cs, js, node, mock...].'); + } + + if (Object.prototype.toString.call(path) !== '[object String]') { + throw Error('The path should be of string type.'); + } + + return addon.metacall_execution_path(tag, path); +}; + const metacall_load_from_file = (tag, paths) => { if (Object.prototype.toString.call(tag) !== '[object String]') { throw Error('Tag should be a string indicating the id of the loader to be used [py, rb, cs, js, node, mock...].'); @@ -150,6 +246,30 @@ const metacall_load_from_memory_export = (tag, code) => { return addon.metacall_load_from_memory_export(tag, code); }; +const metacall_load_from_package = (tag, pkg) => { + if (Object.prototype.toString.call(tag) !== '[object String]') { + throw Error('Tag should be a string indicating the id of the loader to be used [py, rb, cs, js, node, mock...].'); + } + + if (Object.prototype.toString.call(pkg) !== '[object String]') { + throw Error('Package should be a string with the id or path to the package.'); + } + + return addon.metacall_load_from_package(tag, pkg); +}; + +const metacall_load_from_package_export = (tag, pkg) => { + if (Object.prototype.toString.call(tag) !== '[object String]') { + throw Error('Tag should be a string indicating the id of the loader to be used [py, rb, cs, js, node, mock...].'); + } + + if (Object.prototype.toString.call(pkg) !== '[object String]') { + throw Error('Package should be a string with the id or path to the package.'); + } + + return addon.metacall_load_from_package_export(tag, pkg); +}; + const metacall_load_from_configuration = (path) => { if (Object.prototype.toString.call(path) !== '[object String]') { throw Error('Path should be a string indicating the path where the metacall.json is located.'); @@ -207,10 +327,13 @@ const module_exports = { metacallfms, metacall_await, metacall_inspect, + metacall_execution_path, metacall_load_from_file, metacall_load_from_file_export, metacall_load_from_memory, metacall_load_from_memory_export, + metacall_load_from_package, + metacall_load_from_package_export, metacall_load_from_configuration, metacall_load_from_configuration_export, metacall_handle, @@ -250,6 +373,8 @@ const file_extensions_to_tag = { tsx: 'ts', /* Rust Loader */ rs: 'rs', + /* C Loader */ + c: 'c', /* Note: By default js extension uses NodeJS loader instead of JavaScript V8 */ /* Probably in the future we can differenciate between them, but it is not trivial */ diff --git a/source/ports/node_port/package-lock.json b/source/ports/node_port/package-lock.json index bfb3b0d1b7..8fc04f8971 100644 --- a/source/ports/node_port/package-lock.json +++ b/source/ports/node_port/package-lock.json @@ -1,12 +1,12 @@ { "name": "metacall", - "version": "0.5.0", + "version": "0.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "metacall", - "version": "0.5.0", + "version": "0.5.1", "license": "Apache-2.0", "devDependencies": { "mocha": "^9.2.1" diff --git a/source/ports/node_port/package.json b/source/ports/node_port/package.json index f9508ef757..5c15efc0b8 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", diff --git a/source/ports/node_port/test.js b/source/ports/node_port/test.js index fb04ea5b13..424b8c60c6 100644 --- a/source/ports/node_port/test.js +++ b/source/ports/node_port/test.js @@ -2,7 +2,7 @@ * MetaCall NodeJS Port by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,17 +41,28 @@ const waitForMocha = async () => { return new Promise((resolve, reject) => mocha.run(failures => failures ? reject(failures) : resolve())); }; -module.exports = { - main: async () => { - try { - // Run the tests - await waitForMocha(); - } catch (failures) { - if (failures !== 0) { - process.exit(1); - } +const main = async () => { + try { + // Run the tests + await waitForMocha(); + } catch (failures) { + if (failures !== 0) { + process.exit(1); } + } - return 'Tests passed without errors'; - }, + return 'Tests passed without errors'; }; + +/* Allow to execute the test on demand */ +if (process.env['NODE_PORT_TEST_EXPORTS']) { + /* Export the test as a function */ + module.exports = { + main, + }; +} else { + /* Execute the test and print the result */ + void (async () => { + console.log(await main()); + })(); +} diff --git a/source/ports/node_port/test/commands/node_port.txt b/source/ports/node_port/test/commands/node_port.txt deleted file mode 100644 index 7a231f9e18..0000000000 --- a/source/ports/node_port/test/commands/node_port.txt +++ /dev/null @@ -1,3 +0,0 @@ -load node test.js -await main() -exit diff --git a/source/ports/node_port/test/index.js b/source/ports/node_port/test/index.js index c6a71114c2..e7ef89a58b 100644 --- a/source/ports/node_port/test/index.js +++ b/source/ports/node_port/test/index.js @@ -2,7 +2,7 @@ * MetaCall NodeJS Port by Parra Studios * A complete infrastructure for supporting multiple language bindings in MetaCall. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/source/ports/node_port/upload.sh b/source/ports/node_port/upload.sh index 297ced5a9a..f37d4c53a5 100755 --- a/source/ports/node_port/upload.sh +++ b/source/ports/node_port/upload.sh @@ -1,10 +1,10 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # # MetaCall NodeJS Port Deploy Script by Parra Studios # Script utility for deploying MetaCall NodeJS Port to NPM. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -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/CMakeLists.txt b/source/ports/py_port/CMakeLists.txt index c6bd6f3303..83bec99f42 100644 --- a/source/ports/py_port/CMakeLists.txt +++ b/source/ports/py_port/CMakeLists.txt @@ -7,6 +7,8 @@ endif() # External dependencies # +find_package(Python3 COMPONENTS Interpreter REQUIRED) + # # Port name and options # @@ -18,63 +20,123 @@ set(target py_port) message(STATUS "Port ${target}") if(NOT OPTION_BUILD_GUIX) - find_package(Python3 COMPONENTS Interpreter REQUIRED) - if(Python3_VERSION_MAJOR EQUAL 3 AND Python3_VERSION_MINOR GREATER_EQUAL 11) set(PIP_BREAK_SYSTEM_PACKAGES "--break-system-packages") else() set(PIP_BACKWARD_COMPATIBILITY "${CMAKE_COMMAND} -E env SETUPTOOLS_USE_DISTUTILS=stdlib") endif() - install(CODE "execute_process(COMMAND ${PIP_BACKWARD_COMPATIBILITY} pip3 install ${PIP_BREAK_SYSTEM_PACKAGES} ${CMAKE_CURRENT_SOURCE_DIR})") + install(CODE "execute_process(COMMAND ${PIP_BACKWARD_COMPATIBILITY} ${Python3_EXECUTABLE} -m pip install ${PIP_BREAK_SYSTEM_PACKAGES} ${CMAKE_CURRENT_SOURCE_DIR})") endif() -# -# Configure test -# - # Check if loaders are enabled if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB OR NOT OPTION_BUILD_SCRIPTS_NODE) return() endif() +# Enable Rust test if the rs_loader is built +if(OPTION_BUILD_LOADERS_RS) + set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1") +endif() + +# +# Define test (CLI) +# + set(py_port_test "${target}_test") +if(OPTION_BUILD_CLI) + message(STATUS "Test ${py_port_test}") + + add_test(NAME ${target} + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/test.py + ) + + # + # Define test labels + # + + set_property(TEST ${target} + PROPERTY LABELS ${py_port_test} + ) + + include(TestEnvironmentVariables) + + test_environment_variables(${target} + "" + ${TESTS_ENVIRONMENT_VARIABLES} + ${TESTS_ENVIRONMENT_VARIABLES_RS} + ) +endif() + # -# Define test +# Define test (Python) # -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/test/commands/py_port.txt.in - ${CMAKE_CURRENT_BINARY_DIR}/py_port.txt -) +set(py_port_test_exec "${py_port_test}_executable") + +# Check if Python is compiled with Address Sanitizer +if(OPTION_BUILD_ADDRESS_SANITIZER) + check_asan_executable("${Python3_EXECUTABLE}" Python3_ASAN) + if(NOT Python3_ASAN) + # Skip this test because it gives false positives if Python is not compiled with ASan + return() + endif() +endif() + +message(STATUS "Test ${py_port_test_exec}") -# Add test (must be run with MetaCall CLI) -add_test(NAME ${target} - COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$" -D "INPUT=${CMAKE_CURRENT_BINARY_DIR}/py_port.txt" -P "${CMAKE_SOURCE_DIR}/source/cli/metacallcli/test/commands/command_runner.cmake" +# Add test (Python) +add_test(NAME ${py_port_test_exec} + COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test.py" ) # # Define test labels # -set_property(TEST ${target} - PROPERTY LABELS ${py_port_test} -) - -set_tests_properties(${target} PROPERTIES - PASS_REGULAR_EXPRESSION "Tests passed without errors" +set_property(TEST ${py_port_test_exec} + PROPERTY LABELS ${py_port_test_exec} ) include(TestEnvironmentVariables) -# Enable rust test if it is built -if(OPTION_BUILD_LOADERS_RS) - set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1") -endif() - -test_environment_variables(${target} +test_environment_variables(${py_port_test_exec} "" ${TESTS_ENVIRONMENT_VARIABLES} ${TESTS_ENVIRONMENT_VARIABLES_RS} + "METACALL_INSTALL_PATH=${PROJECT_OUTPUT_DIR}" + ${TESTS_SANITIZER_ENVIRONMENT_VARIABLES} + ${TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES} +) + +# +# Define test (Python standalone) +# + +set(py_port_test_exec_alone "${py_port_test}_executable_standalone") + +message(STATUS "Test ${py_port_test_exec_alone}") + +# Add test (Python standalone) +add_test(NAME ${py_port_test_exec_alone} + COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test.py" +) + +# +# Define test labels +# + +set_property(TEST ${py_port_test_exec_alone} + PROPERTY LABELS ${py_port_test_exec_alone} +) + +include(TestEnvironmentVariables) + +test_environment_variables(${py_port_test_exec_alone} + "" + "LOADER_SCRIPT_PATH=${LOADER_SCRIPT_PATH}" + "METACALL_INSTALL_PATH=${PROJECT_OUTPUT_DIR}" + ${TESTS_SANITIZER_ENVIRONMENT_VARIABLES} + ${TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES} ) diff --git a/source/ports/py_port/LICENSE.txt b/source/ports/py_port/LICENSE.txt deleted file mode 100644 index 2e591e57ad..0000000000 --- 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-2024 Vicente Eduardo Ferrer Garcia - - 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 7557376f5f..0000000000 --- a/source/ports/py_port/MANIFEST.in +++ /dev/null @@ -1,9 +0,0 @@ -# Include the license file -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/README.rst b/source/ports/py_port/README.rst index c90d8c46b6..469dad7302 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 ======= @@ -51,11 +51,31 @@ 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 - metacall main.py + python3 main.py Using pointers (calling to a C library) --------------------------------------- diff --git a/source/ports/py_port/VERSION b/source/ports/py_port/VERSION deleted file mode 100644 index 5d4294b912..0000000000 --- a/source/ports/py_port/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.5.1 \ No newline at end of file diff --git a/source/ports/py_port/helper.py b/source/ports/py_port/helper.py deleted file mode 100644 index 86f8513818..0000000000 --- a/source/ports/py_port/helper.py +++ /dev/null @@ -1,240 +0,0 @@ -import sys -import os -import re -import shutil -import tarfile -import subprocess - -import requests - - -def file_size(num, suffix='B'): - for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']: - if abs(num) < 1024.0: - return "%3.1f%s%s" % (num, unit, suffix) - num /= 1024.0 - return "%.1f%s%s" % (num, 'Yi', suffix) - - -def find_assets(patterns): - api_url = 'https://api.github.com/repos/metacall/core/releases/latest' - urls = [] - res = requests.get(api_url) - data = res.json() - data = [li['browser_download_url'] for li in data['assets']] - for p in patterns: - regex = re.compile(p) - urls.append(list(filter(regex.search, data))[0]) - return urls - - -def download(urls): - for url in urls: - filename = '/tmp/{}'.format(url.split("/")[-1]) - - if os.path.isfile(filename + '.tmp'): - os.remove(filename + '.tmp') - - with open(filename + '.tmp', 'wb') as file: - res = requests.get(url, stream=True) - total_length = res.headers.get('content-length') - - if total_length is None or int(total_length) < 4096: - print('Downloading {} from {}\n'.format(url.split("/")[-1], url)) - file.write(res.content) - else: - dl = 0 - total_length = int(total_length) - print('Downloading {} (total: {}) from {}\n'.format(url.split("/")[-1], total_length, url)) - for data in res.iter_content(chunk_size=4096): - dl += len(data) - file.write(data) - done = int(50 * dl / total_length) - sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50 - done))) - sys.stdout.write( - '\r[{}{}] - {}/{}'.format('=' * done, ' ' * (50 - done), - file_size(dl), file_size(total_length)) - ) - sys.stdout.flush() - print('\n') - - os.rename(filename + '.tmp', filename) - - -def unpack(files): - for filename in files: - filename = filename.split("/")[-1] - print('Extracting {} ...'.format(filename)) - with tarfile.open(filename) as file: - file.extractall() - - -def write_install_log(content): - with open('/tmp/mc-install.tmp', 'w') as logger: - logger.write('\n'.join(content)) - - shutil.move('/tmp/mc-install.tmp', '/usr/local/share/metacall/install') - - -def read_install_log(): - with open('/usr/local/share/metacall/install', 'r') as logger: - lines = logger.read().splitlines() - return lines - - -def overwrite(src, dest): - if os.path.isdir(src): - if not os.path.isdir(dest): - os.makedirs(dest) - files = os.listdir(src) - for file in files: - yield from overwrite(os.path.join(src, file), os.path.join(dest, file)) - else: - print('copying {} to {}'.format(src, dest)) - shutil.copyfile(src, dest) - yield str(dest) - - -def spawn(args): - process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - output, error = process.communicate() - - return output, error, process.returncode - - -def pre_install(components): - download(['https://raw.githubusercontent.com/metacall/core/develop/tools/metacall-runtime.sh']) - args = ['bash', '/tmp/metacall-runtime.sh'] - args = args + components - subprocess.call(args) - - -def pre_install_prompt(): - - answers = {'yes': True, 'y': True, 'no': False, 'n': False} - components = ['python', 'ruby', 'netcore7', 'v8', 'nodejs', 'ports'] - args = [] - - try: - while True: - for component in components: - message = '''do you want to install {} (y/n)? '''.format(component) - sys.stdout.write(message) - choice = input().lower() - if choice in answers and answers[choice]: - args.append(component) - elif choice not in answers: - sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n") - exit(0) - if len(args) == 0: - exit(0) - pre_install(args) - break - - except KeyboardInterrupt: - exit(1) - - -def install(ignore=False): - if ignore is False: - if os.path.isfile('/usr/local/bin/metacallcli'): - print('MetaCall CLI is already installed') - exit(0) - pre_install_prompt() - - if os.getuid() != 0: - print('You need to have root privileges to run this script.') - exit(-1) - - os.chdir('/tmp/') - - docs = '' # link to documentation if this script failed to download the cli - - try: - - print('Searching for files ...') - - assets = find_assets([r'metacall-[0-9].[0-9].[0.9]-runtime.tar.gz', - r'metacall-[0-9].[0-9].[0.9]-examples.tar.gz']) - - missing_files = [file for file in assets if not os.path.isfile(file.split('/')[-1])] - - if len(missing_files) != 0: - download(missing_files) - - unpack(assets) - - write_install_log(list(overwrite('/tmp/usr/local/', '/usr/local/'))) - - print('\n') - - output, error, code = spawn(['ldconfig', '-n', '-v', '/usr/local/lib/']) - if code != 0: - print('Failed to install MetaCall\n{}\n' - 'please proceed with the manual installation. {}'.format(error.decode('utf-8'), docs)) - exit(1) - else: - print(output.decode('utf-8')) - - spawn(['chmod', '+x', '/usr/local/bin/metacallcli']) - - print('\nCleaning things up ...') - - shutil.rmtree('/tmp/usr') - for file in assets: - path = '/tmp/' + file.split('/')[-1] - if os.path.isfile(path): - os.remove(path) - - print('MetaCall CLI is successfully installed.') - - except ConnectionError: - print('Downloading process failed, please proceed with the manual installation. {}'.format(docs)) - except tarfile.ExtractError: - print('Extraction process failed, please proceed with the manual installation. {}'.format(docs)) - except KeyboardInterrupt: - print('\nCanceled by user.') - - -def update(): - install(ignore=True) - - -def uninstall(paths): - - for fp in paths: - if os.path.isfile(fp): - os.remove(fp) - - if os.path.isdir('/usr/local/share/metacall'): - shutil.rmtree('/usr/local/share/metacall') - - spawn(['ldconfig']) - - exit(0) - - -def uninstall_prompt(): - paths = read_install_log() - message = '''This action would remove:\n {} -* this action DOES NOT uninstall the python package, only MetaCall CLI and MetaCall libs -* for a complete uninstall you have to run metacall-uninstall && pip uninstall metacall -* (the order of execution is important) - -Proceed (y/n)? '''.format(''.join('''{}\n '''.format(l) for l in paths)) - - answers = {'yes': True, 'y': True, 'no': False, 'n': False} - - try: - while True: - sys.stdout.write(message) - choice = input().lower() - if choice in answers: - if answers[choice]: - uninstall(paths) - else: - exit(0) - else: - sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n") - except KeyboardInterrupt: - exit(1) \ No newline at end of file diff --git a/source/ports/py_port/helper/__init__.py b/source/ports/py_port/helper/__init__.py deleted file mode 100644 index e410e78683..0000000000 --- a/source/ports/py_port/helper/__init__.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python3 - -# MetaCall Python Port by Parra Studios -# A frontend for Python language bindings in MetaCall. -# -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia -# -# 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. - -# TODO: Update to the new install / distributable tarballs - -import sys -import os -import re -import shutil -import tarfile -import subprocess -import requests - -def file_size(num, suffix='B'): - for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']: - if abs(num) < 1024.0: - return "%3.1f%s%s" % (num, unit, suffix) - num /= 1024.0 - return "%.1f%s%s" % (num, 'Yi', suffix) - -def find_assets(patterns): - api_url = 'https://api.github.com/repos/metacall/core/releases/latest' - urls = [] - res = requests.get(api_url) - data = res.json() - data = [li['browser_download_url'] for li in data['assets']] - for p in patterns: - regex = re.compile(p) - urls.append(list(filter(regex.search, data))[0]) - return urls - -def download(urls): - for url in urls: - filename = '/tmp/{}'.format(url.split("/")[-1]) - - if os.path.isfile(filename + '.tmp'): - os.remove(filename + '.tmp') - - with open(filename + '.tmp', 'wb') as file: - res = requests.get(url, stream=True) - total_length = res.headers.get('content-length') - - if total_length is None or int(total_length) < 4096: - print('Downloading {} from {}\n'.format(url.split("/")[-1], url)) - file.write(res.content) - else: - dl = 0 - total_length = int(total_length) - print('Downloading {} (total: {}) from {}\n'.format(url.split("/")[-1], total_length, url)) - for data in res.iter_content(chunk_size=4096): - dl += len(data) - file.write(data) - done = int(50 * dl / total_length) - sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50 - done))) - sys.stdout.write( - '\r[{}{}] - {}/{}'.format('=' * done, ' ' * (50 - done), - file_size(dl), file_size(total_length)) - ) - sys.stdout.flush() - print('\n') - - os.rename(filename + '.tmp', filename) - -def unpack(files): - for filename in files: - filename = filename.split("/")[-1] - print('Extracting {} ...'.format(filename)) - with tarfile.open(filename) as file: - file.extractall() - -def write_install_log(content): - with open('/tmp/mc-install.tmp', 'w') as logger: - logger.write('\n'.join(content)) - - shutil.move('/tmp/mc-install.tmp', '/usr/local/share/metacall/install') - -def read_install_log(): - with open('/usr/local/share/metacall/install', 'r') as logger: - lines = logger.read().splitlines() - return lines - -def overwrite(src, dest): - if os.path.isdir(src): - if not os.path.isdir(dest): - os.makedirs(dest) - files = os.listdir(src) - for file in files: - yield from overwrite(os.path.join(src, file), os.path.join(dest, file)) - else: - print('copying {} to {}'.format(src, dest)) - shutil.copyfile(src, dest) - yield str(dest) - -def spawn(args): - process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - output, error = process.communicate() - - return output, error, process.returncode - -def pre_install(components): - download(['https://raw.githubusercontent.com/metacall/core/develop/tools/metacall-runtime.sh']) - args = ['bash', '/tmp/metacall-runtime.sh'] - args = args + components - subprocess.call(args) - -def pre_install_prompt(): - answers = {'yes': True, 'y': True, 'no': False, 'n': False} - components = ['python', 'ruby', 'netcore', 'v8', 'nodejs', 'ports'] - args = [] - - try: - while True: - for component in components: - message = '''do you want to install {} (y/n)? '''.format(component) - sys.stdout.write(message) - choice = input().lower() - if choice in answers and answers[choice]: - args.append(component) - elif choice not in answers: - sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n") - exit(0) - if len(args) == 0: - exit(0) - pre_install(args) - break - - except KeyboardInterrupt: - exit(1) - -def install(ignore=False): - if ignore is False: - if os.path.isfile('/usr/local/bin/metacallcli'): - print('MetaCall CLI is already installed') - exit(0) - pre_install_prompt() - - if os.getuid() != 0: - print('You need to have root privileges to run this script.') - exit(-1) - - os.chdir('/tmp/') - - docs = '' # link to documentation if this script failed to download the cli - - try: - - print('Searching for files ...') - - assets = find_assets([r'metacall-[0-9].[0-9].[0.9]-runtime.tar.gz', - r'metacall-[0-9].[0-9].[0.9]-examples.tar.gz']) - - missing_files = [file for file in assets if not os.path.isfile(file.split('/')[-1])] - - if len(missing_files) != 0: - download(missing_files) - - unpack(assets) - - write_install_log(list(overwrite('/tmp/usr/local/', '/usr/local/'))) - - print('\n') - - output, error, code = spawn(['ldconfig', '-n', '-v', '/usr/local/lib/']) - if code != 0: - print('Failed to install MetaCall\n{}\n' - 'please proceed with the manual installation. {}'.format(error.decode('utf-8'), docs)) - exit(1) - else: - print(output.decode('utf-8')) - - spawn(['chmod', '+x', '/usr/local/bin/metacallcli']) - - print('\nCleaning things up ...') - - shutil.rmtree('/tmp/usr') - for file in assets: - path = '/tmp/' + file.split('/')[-1] - if os.path.isfile(path): - os.remove(path) - - print('MetaCall CLI is successfully installed.') - - except ConnectionError: - print('Downloading process failed, please proceed with the manual installation. {}'.format(docs)) - except tarfile.ExtractError: - print('Extraction process failed, please proceed with the manual installation. {}'.format(docs)) - except KeyboardInterrupt: - print('\nCanceled by user.') - -def update(): - install(ignore=True) - -def uninstall(paths): - - for fp in paths: - if os.path.isfile(fp): - os.remove(fp) - - if os.path.isdir('/usr/local/share/metacall'): - shutil.rmtree('/usr/local/share/metacall') - - spawn(['ldconfig']) - - exit(0) - -def uninstall_prompt(): - paths = read_install_log() - message = '''This action would remove:\n {} -* this action DOES NOT uninstall the python package, only MetaCall CLI and MetaCall libs -* for a complete uninstall you have to run metacall-uninstall && pip uninstall metacall -* (the order of execution is important) - -Proceed (y/n)? '''.format(''.join('''{}\n '''.format(l) for l in paths)) - - answers = {'yes': True, 'y': True, 'no': False, 'n': False} - - try: - while True: - sys.stdout.write(message) - choice = input().lower() - if choice in answers: - if answers[choice]: - uninstall(paths) - else: - exit(0) - else: - sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n") - except KeyboardInterrupt: - exit(1) diff --git a/source/ports/py_port/metacall/__init__.py b/source/ports/py_port/metacall/__init__.py index ef8a6fd075..412cd2dd18 100644 --- a/source/ports/py_port/metacall/__init__.py +++ b/source/ports/py_port/metacall/__init__.py @@ -3,7 +3,7 @@ # MetaCall Python Port by Parra Studios # A frontend for Python language bindings in MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/source/ports/py_port/metacall/api.py b/source/ports/py_port/metacall/api.py index 6bfb290cca..83f28da451 100644 --- a/source/ports/py_port/metacall/api.py +++ b/source/ports/py_port/metacall/api.py @@ -3,7 +3,7 @@ # MetaCall Python Port by Parra Studios # A frontend for Python language bindings in MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,35 +18,99 @@ # limitations under the License. import os +import re import sys import json -import inspect # TODO: Remove this, check the monkey patching - -if sys.platform == 'win32': - from metacall.module_win32 import metacall_module_load -elif sys.platform == 'linux': - from metacall.module_linux import metacall_module_load -elif sys.platform == 'darwin' or sys.platform == 'cygwin': - print('\x1b[31m\x1b[1m', 'The platform', sys.platform, 'has not been not tested, but we are using linux module as a fallback.', '\x1b[0m') - # TODO: Probably it won't work, but we use it as a fallback, implement other platforms - from metacall.module_linux import metacall_module_load -else: - raise ImportError('MetaCall Python Port is not implemented under this platform.') +import ctypes + +def find_files_recursively(root_dir, pattern): + regex = re.compile(pattern) + matches = [] + for dirpath, dirnames, filenames in os.walk(root_dir): + for filename in filenames: + if regex.search(filename): + matches.append(os.path.join(dirpath, filename)) + return matches + +def platform_install_paths(): + if sys.platform == 'win32': + return { + 'paths': [ os.path.join(os.environ.get('LOCALAPPDATA', ''), 'MetaCall', 'metacall') ], + 'name': r'metacall\.dll' + } + elif sys.platform == 'darwin': + return { + 'paths': [ '/opt/homebrew/lib/', '/usr/local/lib/' ], + 'name': r'libmetacall\.dylib' + } + elif sys.platform == 'linux': + return { + 'paths': [ '/usr/local/lib/', '/gnu/lib/' ], + 'name': r'libmetacall\.so' + } + else: + raise RuntimeError(f"Platform {sys.platform} not supported") + +def search_paths(): + custom_path = os.environ.get('METACALL_INSTALL_PATH') + if custom_path: + return { + 'paths': [ custom_path ], + 'name': r'^(lib)?metacall(d)?\.(so|dylib|dll)$' + } + + return platform_install_paths() + +def find_library(): + search_data = search_paths() + + for path in search_data['paths']: + files = find_files_recursively(path, search_data['name']) + if files: + return files[0] + + raise ImportError(""" + MetaCall library not found, if you have it in a special folder, define it through METACALL_INSTALL_PATH'. + """ + + "Looking for it in the following paths: " + ', '.join(search_data['paths']) + """ + If you do not have it installed, you have three options: + 1) Go to https://github.com/metacall/install and install it. + 2) Contribute to https://github.com/metacall/distributable by providing support for your platform and architecture. + 3) Be a x10 programmer and compile it by yourself, then define the install folder if it is different from the default in os.environ['METACALL_INSTALL_PATH']. + """) + +def metacall_module_load(): + # Check if it is loaded from MetaCall or from Python + if 'py_port_impl_module' in sys.modules: + return sys.modules['py_port_impl_module'] + + # Define the Python host + os.environ['METACALL_HOST'] = 'py' + + # Find the shared library + library_path = find_library() + + # Load MetaCall + lib = ctypes.CDLL(library_path, mode=ctypes.RTLD_GLOBAL) + + # Python Port must have been loaded at this point + if 'py_port_impl_module' in sys.modules: + 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' + ) # Load metacall extension depending on the platform module = metacall_module_load() -# Check if library was found and print error message otherwhise -if module == None: - print('\x1b[31m\x1b[1m', 'You do not have MetaCall installed or we cannot find it.', '\x1b[0m') - print('\x1b[1m', 'Looking for it in the following paths:', sys.path, '\x1b[0m') - print('\x1b[33m\x1b[1m', 'If you do not have it installed, you have three options:', '\x1b[0m') - print('\x1b[1m', ' 1) Go to https://github.com/metacall/install and install it.', '\x1b[0m') - print('\x1b[1m', ' 2) Contribute to https://github.com/metacall/distributable by providing support for your platform and architecture.', '\033[0m') - print('\x1b[1m', ' 3) Be a x10 programmer and compile it by yourself, then define the install folder (if it is different from the default /usr/local/lib) in os.environ[\'LOADER_LIBRARY_PATH\'].', '\x1b[0m') - print('\x1b[33m\x1b[1m', 'If you have it installed in an non-standard folder, please define os.environ[\'LOADER_LIBRARY_PATH\'].', '\x1b[0m') - raise ImportError('MetaCall Python Port was not found') - # Load from file def metacall_load_from_file(tag, paths): return module.metacall_load_from_file(tag, paths) diff --git a/source/ports/py_port/metacall/module_linux.py b/source/ports/py_port/metacall/module_linux.py deleted file mode 100644 index 0a18b32603..0000000000 --- a/source/ports/py_port/metacall/module_linux.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 - -# MetaCall Python Port by Parra Studios -# A frontend for Python language bindings in MetaCall. -# -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia -# -# 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. - -import os -import sys -import re - -def metacall_module_load(): - # Append environment variable or default install path when building manually - sys.path.append(os.environ.get('LOADER_LIBRARY_PATH', os.path.join(os.path.sep, 'usr', 'local', 'lib'))) - - # Find is MetaCall is installed as a distributable tarball - rootdir = os.path.join(os.path.sep, 'gnu', 'store') - regex = re.compile('.*-metacall-.*') - - for root, dirs, _ in os.walk(rootdir): - for folder in dirs: - if regex.match(folder) and not folder.endswith('R'): - sys.path.append(os.path.join(rootdir, folder, 'lib')) - - # Try to load the extension - library_names = ['libpy_loaderd', 'libpy_loader'] - library_found = '' - module = None - - # Find the library - for name in library_names: - try: - module = __import__(name, globals(), locals()) - library_found = name - break - except ImportError as e: - pass - except: - print("Unexpected error while loading the MetaCall Python Port", name, ":", sys.exc_info()[0]) - raise - - return module diff --git a/source/ports/py_port/metacall/module_win32.py b/source/ports/py_port/metacall/module_win32.py deleted file mode 100644 index aed098254c..0000000000 --- a/source/ports/py_port/metacall/module_win32.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 - -# MetaCall Python Port by Parra Studios -# A frontend for Python language bindings in MetaCall. -# -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia -# -# 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. - -import os -import ctypes -from ctypes import wintypes, windll - -def metacall_module_load(): - def enum_process_modules(): - # Get handle of current process - kernel32 = windll.kernel32 - kernel32.GetCurrentProcess.restype = ctypes.c_void_p - hProcess = kernel32.GetCurrentProcess() - - # Load EnumProcessModules either from kernel32.dll or psapi.dll - try: - EnumProcessModulesProc = windll.psapi.EnumProcessModules - except AttributeError: - EnumProcessModulesProc = windll.kernel32.EnumProcessModules - EnumProcessModulesProc.restype = ctypes.c_bool - EnumProcessModulesProc.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_void_p), ctypes.c_ulong, ctypes.POINTER(ctypes.c_ulong)] - - hProcess = kernel32.GetCurrentProcess() - hMods = (ctypes.c_void_p * 1024)() - cbNeeded = ctypes.c_ulong() - if EnumProcessModulesProc(hProcess, hMods, ctypes.sizeof(hMods), ctypes.byref(cbNeeded)): - return hMods - return None - - def get_loaded_module(modules, module_name): - kernel32 = windll.kernel32 - kernel32.GetModuleFileNameA.restype = ctypes.c_ulong - kernel32.GetModuleFileNameA.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_ulong] - - if modules is None: - return None - for module in modules: - cPath = ctypes.c_char_p(b'\0' * 1024) - kernel32.GetModuleFileNameA(module, cPath, ctypes.c_ulong(1024)) - path = cPath.value - if os.path.normpath(path.decode('utf-8')) == os.path.normpath(module_name): - return module - return None - - # Retrieve all loaded modules in the process - modules = enum_process_modules() - - # Get environment variable or default install path when building manually - base_path = os.environ.get('LOADER_LIBRARY_PATH', os.path.join(os.path.sep, 'C:', 'Program Files', 'MetaCall')) - library_names = ['py_loaderd', 'py_loader'] - - for name in library_names: - runtime_module_handle = get_loaded_module(modules, os.path.join(os.path.sep, base_path, name + '.dll')) - if runtime_module_handle is None: - continue - runtime_module = ctypes.CDLL('', handle = runtime_module_handle) # cdecl calling convention - - if runtime_module != None: - func_name = 'PyInit_' + name - if runtime_module[func_name]: - init = runtime_module[func_name] - init.restype = ctypes.py_object - init.argtypes = None - return init() - - return None diff --git a/source/ports/py_port/setup.cfg b/source/ports/py_port/setup.cfg deleted file mode 100644 index 79bc67848f..0000000000 --- a/source/ports/py_port/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[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 diff --git a/source/ports/py_port/setup.py b/source/ports/py_port/setup.py index e085fcfebb..f5094e04c6 100644 --- a/source/ports/py_port/setup.py +++ b/source/ports/py_port/setup.py @@ -3,7 +3,7 @@ # MetaCall Python Port by Parra Studios # A frontend for Python language bindings in MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -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.3', 'description': 'A library for providing inter-language foreign function interface calls', 'long_description': long_description, @@ -52,6 +48,13 @@ # 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', @@ -71,9 +74,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', @@ -95,8 +95,11 @@ # Keywords 'keywords': 'metacall python port ffi polyglot faas serverless', - # Modules - 'py_modules': ['metacall'], + # 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, @@ -111,7 +114,7 @@ # 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'], + # 'sample': ['package_data.dat'], #}, # Although 'package_data' is the preferred approach, in some case you may @@ -122,86 +125,7 @@ } # Exclude base packages -exclude_packages = ['contrib', 'docs', 'test', 'test.py' 'CMakeLists.txt', '.gitignore', 'upload.sh'] - -# TODO: Review helper -# # Detect if metacall port is already installed -# port_installed = False - -# # Append environment variable or default install path when building manually (TODO: Cross-platform paths) -# sys.path.append(os.environ.get('PORT_LIBRARY_PATH', os.path.join(os.path.sep, 'usr', 'local', 'lib'))); - -# # Find is MetaCall is installed as a distributable tarball (TODO: Cross-platform paths) -# rootdir = os.path.join(os.path.sep, 'gnu', 'store') -# regex = re.compile('.*-metacall-.*') - -# for root, dirs, _ in os.walk(rootdir): -# for folder in dirs: -# if regex.match(folder) and not folder.endswith('R'): -# sys.path.append(os.path.join(rootdir, folder, 'lib')) - -# TODO: Review helper -# # Find if module is installed -# if sys.version_info[0] < 3: -# # Python 2.7 -# import imp -# try: -# imp.find_module('_py_port') -# port_installed = True -# except ImportError: -# try: -# imp.find_module('_py_portd') -# port_installed = True -# except ImportError: -# pass -# elif sys.version_info[0] >= 3 and sys.version_info[1] <= 3: -# # Python <= 3.3 -# import importlib -# py_port = importlib.find_loader('_py_port') -# port_installed = py_port is not None -# if port_installed == False: -# py_port = importlib.find_loader('_py_portd') -# port_installed = py_port is not None -# elif sys.version_info[0] >= 3 and sys.version_info[1] > 3: -# # Python >= 3.4 -# import importlib -# py_port = importlib.util.find_spec("_py_port") -# port_installed = py_port is not None -# if port_installed == False: -# py_port = importlib.util.find_spec("_py_portd") -# port_installed = py_port is not None - -# TODO: This code is very interesting for providing commands to the end user. -# pip cannot execute arbitrary code as pre/post install hook when the package is being installed. -# So it is impossible to install the binaries unless we add extra commands after install. -# At this moment there is a common solution for installing binaries depending on Bash/PowerShell -# that is OS dependant and not language dependant. By the moment we will use the new way of install -# instead of the old one, but we keep the ./helper folder in order to provide future support for -# extra commands, although the main idea is to keep the OS dependant install, this can be useful -# for updating or doing Python related things. Meanwhile, it will be avoided. -exclude_packages.extend(['helper', 'helper.py']) - -# TODO: Review helper -# if port_installed == True: -# # Exclude helper package if port is already installed -# exclude_packages.append('helper') -# else: -# # List run-time dependencies here. These will be installed by pip when -# # your project is installed. For an analysis of "install_requires" vs pip's -# # requirements files see: -# # https://packaging.python.org/en/latest/requirements.html -# options['install_requires'] = ['peppercorn', 'requests'] - -# # To provide executable scripts, use entry points in preference to the -# # "scripts" keyword. Entry points provide cross-platform support and allow -# # pip to create the appropriate form of executable for the target platform. -# options['entry_points'] = { -# 'console_scripts': [ -# 'metacall-install=helper:install', -# 'metacall-uninstall=helper:uninstall_prompt', -# 'metacall-update=helper:update' -# ], -# } +exclude_packages = ['contrib', 'docs', 'test', 'test.py', 'CMakeLists.txt', '.gitignore', 'upload.sh'] # Define required packages options['packages'] = find_packages(exclude=exclude_packages) diff --git a/source/ports/py_port/test.py b/source/ports/py_port/test.py index 034a4ac690..7405b9c3cc 100644 --- a/source/ports/py_port/test.py +++ b/source/ports/py_port/test.py @@ -16,4 +16,7 @@ def main(): if len(result.errors) + len(result.failures) == 0: return 'Tests passed without errors' else: - return '' + exit(1) + +if __name__ == "__main__": + main() diff --git a/source/ports/py_port/test/commands/py_port.txt.in b/source/ports/py_port/test/commands/py_port.txt.in deleted file mode 100644 index 2a9019bbc8..0000000000 --- a/source/ports/py_port/test/commands/py_port.txt.in +++ /dev/null @@ -1,3 +0,0 @@ -load py ${CMAKE_CURRENT_SOURCE_DIR}/test.py -call main() -exit diff --git a/source/ports/py_port/upload.sh b/source/ports/py_port/upload.sh index 2ca4f09fde..a3aba92f0d 100755 --- a/source/ports/py_port/upload.sh +++ b/source/ports/py_port/upload.sh @@ -4,7 +4,7 @@ # MetaCall Python Port Deploy Script by Parra Studios # Script utility for deploying MetaCall Python Port to PyPi. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia +# Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,19 +22,21 @@ 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." 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 -python3 setup.py sdist bdist_wheel +python3 -m pip install --user --upgrade twine setuptools wheel build +python3 -m build python3 -m twine check dist/* python3 -m twine upload dist/* # Delete output -rm -rf dist/* build/* +rm -rf dist build *.egg-info diff --git a/source/ports/rb_port/.gitignore b/source/ports/rb_port/.gitignore new file mode 100644 index 0000000000..16e37a4076 --- /dev/null +++ b/source/ports/rb_port/.gitignore @@ -0,0 +1,2 @@ +*.gem +*.rbc diff --git a/source/ports/rb_port/CMakeLists.txt b/source/ports/rb_port/CMakeLists.txt index 1d2cbf5be8..0827203ac5 100644 --- a/source/ports/rb_port/CMakeLists.txt +++ b/source/ports/rb_port/CMakeLists.txt @@ -3,16 +3,6 @@ if(NOT OPTION_BUILD_PORTS OR NOT OPTION_BUILD_PORTS_RB OR NOT OPTION_BUILD_LOADE return() endif() -# TODO: This port is not passing tests properly in MacOS and Windows. -# In any case this implementation will be deleted eventually (once SWIG gets removed), -# so there is no need to make it work anyway. In any case this project should be reviewed. -include(Portability) - -if(PROJECT_OS_FAMILY STREQUAL win32 OR PROJECT_OS_FAMILY STREQUAL macos) - message(WARNING "Port rb_port does not work on Windows neither MacOS") - return() -endif() - # # External dependencies # @@ -34,291 +24,71 @@ set(target rb_port) # Exit here if required dependencies are not met message(STATUS "Port ${target}") -# Set API export file and macro -string(TOUPPER ${target} target_upper) -set(export_file "include/${target}/${target}_api.h") -set(export_macro "${target_upper}_API") - -# -# Sources -# - -set(interface_path "${CMAKE_CURRENT_SOURCE_DIR}/interface/${target}") -set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") -set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") - -set(interfaces - ${interface_path}/rb_port.i -) - -set(headers - ${include_path}/rb_port.h -) - -set(sources - ${source_path}/rb_port.c -) -# Group source files -set(interface_group "Interface Files (SWIG)") -set(header_group "Header Files (API)") -set(source_group "Source Files") -source_group_by_path(${interface_path} "\\\\.i$" - ${interface_group} ${interfaces}) -source_group_by_path(${include_path} "\\\\.h$|\\\\.hpp$" - ${header_group} ${headers}) -source_group_by_path(${source_path} "\\\\.cpp$|\\\\.c$|\\\\.h$|\\\\.hpp$" - ${source_group} ${sources}) - -# -# SWIG Configuration -# - -# Set SWIG flags -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - list(APPEND CMAKE_SWIG_FLAGS "-DDEBUG") -else() - list(APPEND CMAKE_SWIG_FLAGS "-DNDEBUG") +# Check for test dependencies +if(NOT OPTION_BUILD_LOADERS_PY) + message(WARNING "Enable Python Loader [-DOPTION_BUILD_LOADERS_PY=ON] for enabling tests for Ruby Port") + return() endif() -# Set SWIG include path -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/interface") - # -# Create library +# Define test (CLI) # -foreach(file ${interfaces} ${headers} ${sources}) - set_source_files_properties( - ${file} - PROPERTY SWIG_FLAGS "-ruby" "-includeall" - ) +set(rb_port_test "${target}_test") +set(rb_port_test_path "${CMAKE_CURRENT_SOURCE_DIR}/test/run.rb") - set_source_files_properties( - ${file} - PROPERTIES CPLUSPLUS OFF - ) -endforeach() +if(OPTION_BUILD_CLI) + message(STATUS "Test ${rb_port_test}") -if(${CMAKE_VERSION} VERSION_LESS "3.8.0") - swig_add_module(${target} - ruby - ${interfaces} - ${headers} - ${sources} - ) -else() - swig_add_library(${target} - LANGUAGE ruby - SOURCES ${interfaces} ${headers} ${sources} - OUTPUT_DIR "${PROJECT_OUTPUT_DIR}" + add_test(NAME ${rb_port_test} + COMMAND $<TARGET_FILE:metacallcli> "${rb_port_test_path}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/test" ) -endif() - -# -# Dependecies -# - -add_dependencies(${SWIG_MODULE_${target}_REAL_NAME} - ${META_PROJECT_NAME}::metacall -) - -# Create namespaced alias -add_library(${META_PROJECT_NAME}::${target} ALIAS ${SWIG_MODULE_${target}_REAL_NAME}) - -# Export library for downstream projects -export(TARGETS ${SWIG_MODULE_${target}_REAL_NAME} NAMESPACE ${META_PROJECT_NAME}:: FILE ${PROJECT_BINARY_DIR}/cmake/${target}/${target}-export.cmake) - -# Create API export header -generate_export_header(${SWIG_MODULE_${target}_REAL_NAME} - EXPORT_FILE_NAME ${export_file} - EXPORT_MACRO_NAME ${export_macro} -) - -# -# Project options -# - -set_target_properties(${SWIG_MODULE_${target}_REAL_NAME} - PROPERTIES - ${DEFAULT_PROJECT_OPTIONS} - FOLDER "${IDE_FOLDER}" - - # Set Ruby extension properies - SUFFIX ".so" -) - -# -# Include directories -# -target_include_directories(${SWIG_MODULE_${target}_REAL_NAME} - PRIVATE - ${PROJECT_BINARY_DIR}/source/include - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include - - $<TARGET_PROPERTY:${META_PROJECT_NAME}::metacall,INCLUDE_DIRECTORIES> # MetaCall includes - ${Ruby_INCLUDE_DIRS} # Ruby includes - - PUBLIC - ${DEFAULT_INCLUDE_DIRECTORIES} - - INTERFACE - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> - $<INSTALL_INTERFACE:include> -) - -# -# Libraries -# - -swig_link_libraries(${target} - PRIVATE - ${Ruby_LIBRARY} # Ruby libraries - - ${META_PROJECT_NAME}::metacall - - PUBLIC - ${DEFAULT_LIBRARIES} - INTERFACE -) - -# -# Compile definitions -# - -target_compile_definitions(${SWIG_MODULE_${target}_REAL_NAME} - PRIVATE - - PUBLIC - $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:${target_upper}_STATIC_DEFINE> - ${DEFAULT_COMPILE_DEFINITIONS} - $<$<BOOL:${MSVC}>:RB_PORT_USINGSWIG_EXPORTS> - - INTERFACE -) - -# -# Compile options -# - -target_compile_options(${SWIG_MODULE_${target}_REAL_NAME} - PRIVATE - - PUBLIC - ${DEFAULT_COMPILE_OPTIONS} - - INTERFACE -) - -include(Portability) - -target_compile_options(${target} - PRIVATE - - # Fix Ruby MacOSX LLVM bug - # '__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes - $<$<AND:$<STREQUAL:${PROJECT_OS_FAMILY},macos>,$<OR:$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>,$<STREQUAL:${CMAKE_CXX_COMPILER_ID},AppleClang>>>:-fdeclspec> - - # Disable warnings (Clang, GCC) for unused parameters and variables generated by Swig - $<$<OR:$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>,$<STREQUAL:${CMAKE_CXX_COMPILER_ID},AppleClang>,$<STREQUAL:${CMAKE_CXX_COMPILER_ID},GNU>>:-Wno-unused-parameter> - $<$<OR:$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>,$<STREQUAL:${CMAKE_CXX_COMPILER_ID},AppleClang>,$<STREQUAL:${CMAKE_CXX_COMPILER_ID},GNU>>:-Wno-unused-variable> - - PUBLIC - ${DEFAULT_COMPILE_OPTIONS} - - INTERFACE -) - -# -# Linker options -# - -target_link_libraries(${SWIG_MODULE_${target}_REAL_NAME} - PRIVATE - ${META_PROJECT_NAME}::metacall - - PUBLIC - ${DEFAULT_LINKER_OPTIONS} - - INTERFACE -) - -# -# Deployment -# - -# Library -install(TARGETS ${SWIG_MODULE_${target}_REAL_NAME} - EXPORT "${target}-export" COMPONENT dev - RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT runtime - LIBRARY DESTINATION ${INSTALL_SHARED} COMPONENT runtime - ARCHIVE DESTINATION ${INSTALL_LIB} COMPONENT dev -) - -# -# Configure test -# + # + # Define test labels + # -# Check if port is enabled -if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB) - return() -endif() + set_property(TEST ${rb_port_test} + PROPERTY LABELS ${rb_port_test} + ) -set(rb_port_test "${target}_test") -set(rb_port_test_path "${PROJECT_OUTPUT_DIR}/${rb_port_test}.rb") + include(TestEnvironmentVariables) -# Require module name -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - get_target_property(DEBUG_POSTFIX ${SWIG_MODULE_${target}_REAL_NAME} "DEBUG_POSTFIX") - set(RB_PORT_NAME "${SWIG_MODULE_${target}_REAL_NAME}${DEBUG_POSTFIX}") -else() - set(RB_PORT_NAME "${SWIG_MODULE_${target}_REAL_NAME}") + test_environment_variables(${rb_port_test} + "" + ${TESTS_ENVIRONMENT_VARIABLES} + ) endif() -# Module object instance (capitalized) -string(SUBSTRING "${RB_PORT_NAME}" 0 1 RB_PORT_FIRST) -string(TOUPPER "${RB_PORT_FIRST}" RB_PORT_FIRST_UPPER) -string(SUBSTRING "${RB_PORT_NAME}" 1 -1 RB_PORT_LAST) -set(RB_PORT_OBJ "${RB_PORT_FIRST_UPPER}${RB_PORT_LAST}") - -configure_file(test/run.rb.in ${rb_port_test_path}) - # -# Define test +# Define test (Ruby) # -if(OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER) - # TODO: This test fails when run with sanitizers: - # - # Sanitizer: - # ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD. - # For solving the issue compile the test with sanitizers when enabled or preload asan - # - # Thread Sanitizer: - # /usr/local/metacall/build/rb_port_test.rb:4:in `require_relative': /usr/lib/x86_64-linux-gnu/libtsan.so.2: cannot allocate memory in static TLS block - /usr/local/metacall/build/rb_portd.so (LoadError) - # from /usr/local/metacall/build/rb_port_test.rb:4:in `<main>' - return() -endif() +set(rb_port_test_executable "${rb_port_test}_executable") + +message(STATUS "Test ${rb_port_test_executable}") -add_test(NAME ${target} - COMMAND ${Ruby_EXECUTABLE} ${rb_port_test_path} +add_test(NAME ${rb_port_test_executable} + COMMAND ${Ruby_EXECUTABLE} "${rb_port_test_path}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/test" ) # # Define test labels # -set_property(TEST ${target} - PROPERTY LABELS ${rb_port_test} +set_property(TEST ${rb_port_test_executable} + PROPERTY LABELS ${rb_port_test_executable} ) include(TestEnvironmentVariables) -test_environment_variables(${target} +test_environment_variables(${rb_port_test_executable} "" ${TESTS_ENVIRONMENT_VARIABLES} + "METACALL_INSTALL_PATH=${PROJECT_OUTPUT_DIR}" + ${TESTS_SANITIZER_ENVIRONMENT_VARIABLES} + ${TESTS_SANITIZER_PRELOAD_ENVIRONMENT_VARIABLES} ) diff --git a/source/ports/rb_port/interface/rb_port/rb_port.i b/source/ports/rb_port/interface/rb_port/rb_port.i deleted file mode 100644 index 7316e756f5..0000000000 --- a/source/ports/rb_port/interface/rb_port/rb_port.i +++ /dev/null @@ -1,67 +0,0 @@ -/* - * MetaCall SWIG Wrapper by Parra Studios - * A complete infrastructure for supporting multiple language bindings in MetaCall. - * - * Copyright (C) 2016 - 2024 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_SWIG_WRAPPER_RB_PORT_I -#define METACALL_SWIG_WRAPPER_RB_PORT_I 1 - -/* -- Headers -- */ - -#if defined(SWIG) && defined(SWIGRUBY) - - #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) - %module rb_portd - #else - %module rb_port - #endif - - %{ - #include <rb_port/rb_port.h> - - #include <metacall/metacall_api.h> - #include <metacall/metacall.h> - #include <metacall/metacall_value.h> - - #include <ruby.h> - %} - - %include <rb_port/rb_port.h> - - /* Note: This should not be necessary because we do not allow to use ports outside MetaCall */ - /* - %init - %{ - metacall_initialize(); - %} - */ - - %import <rb_port/rb_port_impl.i> - - %include <metacall/metacall_api.h> - - #ifdef METACALL_API - # undef METACALL_API - # define METACALL_API - #endif - - %include <metacall/metacall.h> - -#endif /* SWIG && SWIGRUBY */ - -#endif /* METACALL_SWIG_WRAPPER_RB_PORT_I */ diff --git a/source/ports/rb_port/interface/rb_port/rb_port_impl.i b/source/ports/rb_port/interface/rb_port/rb_port_impl.i deleted file mode 100644 index bd0820f2b3..0000000000 --- a/source/ports/rb_port/interface/rb_port/rb_port_impl.i +++ /dev/null @@ -1,408 +0,0 @@ -/* - * MetaCall SWIG Wrapper by Parra Studios - * A complete infrastructure for supporting multiple language bindings in MetaCall. - * - * Copyright (C) 2016 - 2024 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_SWIG_WRAPPER_RB_PORT_IMPL_I -#define METACALL_SWIG_WRAPPER_RB_PORT_IMPL_I 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -- Ignores -- */ - -%ignore metacall_null_args; - -%ignore metacallv; - -%ignore metacallvf; - -%ignore metacall_serial; /* TODO */ - -%ignore metacall_register; /* TODO */ - -%ignore metacall_load_from_package; /* TODO */ - -/* -- Type Maps -- */ - -/** -* @brief -* Transform load mechanism from Ruby string into -* a valid load from memory format (buffer and size) -*/ -%typemap(in) (const char * buffer, size_t size, void ** handle) -{ - char * buffer_str = StringValuePtr($input); - - size_t length = RSTRING_LEN($input); - - $1 = buffer_str; - - $2 = (length + 1); -} - -/** -* @brief -* Transform load mechanism from Ruby array into -* a valid load from file format (array of strings) -*/ -%typemap(in) (const char * paths[], size_t size, void ** handle) -{ - size_t iterator, size = RARRAY_LEN($input); - - VALUE * array_ptr = RARRAY_PTR($input); - - if (size == 0) - { - rb_raise(rb_eArgError, "Empty script path list"); - - return Qnil; - } - - $1 = (char **)malloc(sizeof(char *) * size); - - if ($1 == NULL) - { - rb_raise(rb_eArgError, "Invalid argument allocation"); - - SWIG_fail; - } - - $2 = size; - - for (iterator = 0; iterator < size; ++iterator, ++array_ptr) - { - size_t length = RSTRING_LEN(*array_ptr); - - $1[iterator] = malloc(sizeof(char) * (length + 1)); - - if ($1[iterator] == NULL) - { - size_t alloc_iterator; - - for (alloc_iterator = 0; alloc_iterator < iterator; ++alloc_iterator) - { - free($1[alloc_iterator]); - } - - free($1); - - rb_raise(rb_eArgError, "Invalid string path allocation"); - - SWIG_fail; - } - - memcpy($1[iterator], StringValuePtr(*array_ptr), length); - - $1[iterator][length] = '\0'; - } -} - -/** -* @brief -* Transform variadic arguments from Ruby into -* a valid metacallv format with values -*/ -%typemap(in) (const char * name, ...) -{ - void ** args; - size_t args_size, args_count; - - /* Format string */ - $1 = RSTRING_PTR($input); - - /* Variable length arguments */ - if (argc >= 1) - { - args_size = argc - 1; - } - else - { - rb_raise(rb_eArgError, "Invalid number of arguments"); - - return Qnil; - } - - if (args_size > 0) - { - /* TODO: Remove this by a local array? */ - args = (void **) malloc(args_size * sizeof(void *)); - - if (args == NULL) - { - rb_raise(rb_eArgError, "Invalid argument allocation"); - - SWIG_fail; - } - - for (args_count = 0; args_count < args_size; ++args_count) - { - VALUE rb_arg = argv[args_count + 1]; - - int rb_arg_type = TYPE(rb_arg); - - if (rb_arg_type == T_TRUE) - { - boolean b = 1L; - - args[args_count] = metacall_value_create_bool(b); - } - else if (rb_arg_type == T_FALSE) - { - boolean b = 0L; - - args[args_count] = metacall_value_create_bool(b); - } - else if (rb_arg_type == T_FIXNUM) - { - int i = FIX2INT(rb_arg); - - args[args_count] = metacall_value_create_int(i); - } - else if (rb_arg_type == T_BIGNUM) - { - long l = NUM2LONG(rb_arg); - - args[args_count] = metacall_value_create_long(l); - } - else if (rb_arg_type == T_FLOAT) - { - double d = NUM2DBL(rb_arg); - - args[args_count] = metacall_value_create_double(d); - } - else if (rb_arg_type == T_STRING) - { - long length = RSTRING_LEN(rb_arg); - - char * str = StringValuePtr(rb_arg); - - if (length > 0 && str != NULL) - { - args[args_count] = metacall_value_create_string(str, (size_t)length); - } - } - else if (rb_arg_type == T_NIL) - { - args[args_count] = metacall_value_create_null(); - } - else - { - size_t alloc_iterator; - - for (alloc_iterator = 0; alloc_iterator < args_count; ++alloc_iterator) - { - metacall_value_destroy(args[alloc_iterator]); - } - - /* TODO: Remove this by a local array? */ - free(args); - - rb_raise(rb_eArgError, "Invalid argument allocation"); - - SWIG_fail; - - return Qnil; - } - } - } - else - { - args = NULL; - } - - $2 = (void *) args; -} - -/* -- Features -- */ - -/** -* @brief -* Execute the load from memory -* -* @return -* Zero if success, different from zero otherwise -*/ -%feature("action") metacall_load_from_memory -{ - const char * tag = (const char *)arg1; - - char * buffer = (char *)arg2; - - size_t size = (size_t)arg3; - - result = metacall_load_from_memory(tag, (const char *)buffer, size, NULL); -} - -/** -* @brief -* Execute the load from file -* -* @return -* Zero if success, different from zero otherwise -*/ -%feature("action") metacall_load_from_file -{ - const char * tag = (const char *)arg1; - - char ** paths = (char **)arg2; - - size_t iterator, size = arg3; - - result = metacall_load_from_file(tag, (const char **)paths, size, NULL); - - for (iterator = 0; iterator < size; ++iterator) - { - free(paths[iterator]); - } - - free(paths); -} - -/** -* @brief -* Execute the call and transform return -* value into a valid Ruby format -* -* @return -* A value converted into Ruby format -*/ -%feature("action") metacall -{ - size_t args_count, args_size; - void ** args; - void * ret; - - args_size = argc - 1; - args = (void **) arg2; - - if (args != NULL) - { - /* Execute call */ - ret = metacallv(arg1, args); - - /* Clear args */ - for (args_count = 0; args_count < args_size; ++args_count) - { - metacall_value_destroy(args[args_count]); - } - - /* TODO: Remove this by a local array? */ - free(args); - } - else - { - /* Execute call */ - ret = metacallv(arg1, metacall_null_args); - } - - /* Return value */ - if (ret != NULL) - { - switch (metacall_value_id(ret)) - { - - case METACALL_BOOL : - { - boolean b = metacall_value_to_bool(ret); - - /*$result*/ vresult = (b == 0L) ? Qfalse : Qtrue; - - break; - } - - case METACALL_CHAR : - { - /*$result*/ vresult = INT2FIX((char)metacall_value_to_char(ret)); - - break; - } - - case METACALL_SHORT : - { - /*$result*/ vresult = INT2FIX((int)metacall_value_to_short(ret)); - - break; - } - - case METACALL_INT : - { - /*$result*/ vresult = INT2FIX(metacall_value_to_int(ret)); - - break; - } - - case METACALL_LONG : - { - /*$result*/ vresult = LONG2NUM(metacall_value_to_long(ret)); - - break; - } - - case METACALL_FLOAT : - { - /*$result*/ vresult = DBL2NUM((double)metacall_value_to_float(ret)); - - break; - } - - case METACALL_DOUBLE : - { - /*$result*/ vresult = DBL2NUM(metacall_value_to_double(ret)); - - break; - } - - case METACALL_STRING : - { - /*$result*/ vresult = rb_str_new_cstr(metacall_value_to_string(ret)); - - break; - } - - case METACALL_NULL : - { - /*$result*/ vresult = Qnil; - - break; - } - - default : - { - rb_raise(rb_eArgError, "Unsupported return type"); - - /*$result*/ vresult = Qnil; - } - } - - metacall_value_destroy(ret); - } - else - { - /*$result*/ vresult = Qnil; - } - - return /*$result*/ vresult; -} - -#ifdef __cplusplus -} -#endif - -#endif /* METACALL_SWIG_WRAPPER_RB_PORT_IMPL_I */ diff --git a/source/ports/rb_port/package/lib/metacall.rb b/source/ports/rb_port/package/lib/metacall.rb index 29d1ce90d6..e889f03ea9 100644 --- a/source/ports/rb_port/package/lib/metacall.rb +++ b/source/ports/rb_port/package/lib/metacall.rb @@ -1,3 +1,151 @@ -class MetaCall +#!/usr/bin/ruby + +require 'find' +require 'rbconfig' +require 'fiddle' + +module MetaCall + extend self + + private + + def find_files_recursively(root_dir, pattern) + regex = Regexp.new(pattern) + matches = [] + + if Dir.exist?(root_dir) + Find.find(root_dir) do |path| + matches << path if File.file?(path) && regex.match?(File.basename(path)) + end + end + + matches + end + + def platform_install_paths + host_os = RbConfig::CONFIG['host_os'] + + case host_os + when /mswin|mingw|cygwin/ + { + paths: [ File.join(ENV['LOCALAPPDATA'].to_s, 'MetaCall', 'metacall') ], + name: 'metacall\.dll' + } + when /darwin/ + { + paths: [ '/opt/homebrew/lib/', '/usr/local/lib/' ], + name: 'libmetacall\.dylib' + } + when /linux/ + { + paths: [ '/usr/local/lib/', '/gnu/lib/' ], + name: 'libmetacall\.so' + } + else + raise "Platform #{host_os} not supported" + end + end + + def search_paths + custom_path = ENV['METACALL_INSTALL_PATH'] + + if custom_path + { + paths: [ custom_path ], + name: '^(lib)?metacall(d)?\.(so|dylib|dll)$' + } + else + platform_install_paths + end + end + + def find_library + search_data = search_paths + + search_data[:paths].each do |path| + files = find_files_recursively(path, search_data[:name]) + return files.first unless files.empty? + end + + raise LoadError, <<~ERROR + MetaCall library not found. If you have it in a special folder, define it using the METACALL_INSTALL_PATH environment variable. + Searched in: #{search_data[:paths].join(', ')} + + If you do not have it installed, you have three options: + 1) Go to https://github.com/metacall/install and install it. + 2) Contribute to https://github.com/metacall/distributable by providing support for your platform and architecture. + 3) Be a x10 programmer and compile it yourself, then define the install folder using METACALL_INSTALL_PATH. + ERROR + end + + def metacall_module_load + # Check if already loaded + if defined?(MetaCallRbLoaderPort) + return MetaCallRbLoaderPort + end + + # Set environment variable for the host + ENV['METACALL_HOST'] = 'rb' + + # Find and load the MetaCall shared library + library_path = find_library + + begin + # Load the shared library globally + Fiddle::Handle.new(library_path, Fiddle::RTLD_GLOBAL | Fiddle::RTLD_NOW) + rescue Fiddle::DLError => e + raise LoadError, "Failed to load MetaCall library at #{library_path}: #{e.message}" + end + + # Check again if the port was loaded + if defined?(MetaCallRbLoaderPort) + return MetaCallRbLoaderPort + else + raise LoadError, 'MetaCall was found but failed to load MetaCallRbLoaderPort' + end + end + + # 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) + MetaCallRbLoaderPort.metacall_load_from_file(tag, paths) + end + + def metacall_load_from_memory(tag, script) + MetaCallRbLoaderPort.metacall_load_from_memory(tag, script) + end + + def metacall(function_name, *args) + MetaCallRbLoaderPort.metacall(function_name, *args) + end + + def metacall_inspect() + MetaCallRbLoaderPort.metacall_inspect() + end end diff --git a/source/ports/rb_port/package/metacall-0.0.1.gem b/source/ports/rb_port/package/metacall-0.0.1.gem deleted file mode 100644 index 851e7ef987..0000000000 Binary files a/source/ports/rb_port/package/metacall-0.0.1.gem and /dev/null differ diff --git a/source/ports/rb_port/test/run.rb b/source/ports/rb_port/test/run.rb new file mode 100644 index 0000000000..cba7d6842c --- /dev/null +++ b/source/ports/rb_port/test/run.rb @@ -0,0 +1,45 @@ +#!/usr/bin/ruby + +require 'test/unit' +require File.expand_path("../package/lib/metacall.rb") + +class RbPortTest < Test::Unit::TestCase + + # MetaCall (Python from memory) + def test_python_memory + script = <<~SCRIPT +def inline_multiply_mem(left: int, right: int) -> int: + return left * right +def inline_hello(left: int, right: int) -> int: + print('Helloo', left, ' ', right) + return left * right +SCRIPT + + assert_equal(0, MetaCall::metacall_load_from_memory('py', script)) + + assert_equal(4, MetaCall::metacall('inline_multiply_mem', 2, 2)) + + assert_equal(200, MetaCall::metacall('inline_hello', 10, 20)) + end + + # MetaCall (Python) + def test_python + assert_equal(0, MetaCall::metacall_load_from_file('py', ['example.py'])) + + assert_equal(nil, MetaCall::metacall('hello')) + + assert_equal(35, MetaCall::metacall('multiply', 5, 7)) + end + + # MetaCall (Ruby) + def test_ruby + assert_equal(0, MetaCall::metacall_load_from_file('rb', ['hello.rb'])) + + assert_equal(nil, MetaCall::metacall('say_null')) + + assert_equal(12, MetaCall::metacall('say_multiply', 3, 4)) + + assert_equal('Hello world!', MetaCall::metacall('say_hello', 'world')) + end + +end diff --git a/source/ports/rb_port/test/run.rb.in b/source/ports/rb_port/test/run.rb.in deleted file mode 100644 index fe0180210d..0000000000 --- a/source/ports/rb_port/test/run.rb.in +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/ruby - -require 'test/unit' -require_relative '@RB_PORT_NAME@' - -class RbPortTest < Test::Unit::TestCase - - @@meta = @RB_PORT_OBJ@.method(:metacall) - - # MetaCall (Python from memory) - def test_python_memory - script = '#!/usr/bin/env python3\n' \ - 'def inline_multiply_mem(left: int, right: int) -> int:\n' \ - ' return left * right;\n' - 'def inline_hello(left: int, right: int) -> int:\n' \ - ' print(\'Helloo\', left, \' \', right);\n' - ' return;\n' - - assert_equal(0, @RB_PORT_OBJ@.metacall_load_from_memory('py', script)) - - #assert_equal(4, @@meta.call('inline_multiply_mem', 2, 2)) - - assert_equal(nil, @@meta.call('inline_hello', 10, 20)) - end - - # MetaCall (Python) - def test_python - assert_equal(0, @RB_PORT_OBJ@.metacall_load_from_file('py', ['example.py'])) - - assert_equal(nil, @@meta.call('hello')) - - assert_equal(35, @@meta.call('multiply', 5, 7)) - end - - # MetaCall (Ruby) - def test_ruby - assert_equal(0, @RB_PORT_OBJ@.metacall_load_from_file('rb', ['hello.rb'])) - - assert_equal(nil, @@meta.call('say_null')) - - assert_equal(12, @@meta.call('say_multiply', 3, 4)) - - assert_equal('Hello world!', @@meta.call('say_hello', 'world')) - end - -end diff --git a/source/ports/rs_port/.vscode/launch.json b/source/ports/rs_port/.vscode/launch.json index 684cfc3471..838674c311 100644 --- a/source/ports/rs_port/.vscode/launch.json +++ b/source/ports/rs_port/.vscode/launch.json @@ -103,6 +103,26 @@ "args": [], "envFile": "${workspaceFolder}${/}.vscode${/}.env", "cwd": "${workspaceFolder}" - } + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug integration test 'metacall_handle_test'", + "cargo": { + "args": [ + "test", + "--no-run", + "--test=metacall_handle_test", + "--package=metacall" + ], + "filter": { + "name": "metacall_handle_test", + "kind": "test" + } + }, + "args": [], + "envFile": "${workspaceFolder}${/}.vscode${/}.env", + "cwd": "${workspaceFolder}" + }, ] } \ No newline at end of file diff --git a/source/ports/rs_port/CMakeLists.txt b/source/ports/rs_port/CMakeLists.txt index 54fbcbca14..972c34922d 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}" ) @@ -233,7 +232,7 @@ set(RS_PORT_BUILD_ENVIRONMENT_VARIABLES "PROJECT_OUTPUT_DIR = { value = \"${PROJECT_OUTPUT_DIR}\", force = true }" ) -set(RS_PORT_CONFIG_ENV_FILE "${CMAKE_CURRENT_SOURCE_DIR}/config.toml") +set(RS_PORT_CONFIG_ENV_FILE "${CMAKE_CURRENT_SOURCE_DIR}/.cargo/config.toml") file(WRITE ${RS_PORT_CONFIG_ENV_FILE} "[env]\n") diff --git a/source/ports/rs_port/Cargo.toml b/source/ports/rs_port/Cargo.toml index 25789507be..51428b0339 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.5.4" [lib] crate-type = ["lib"] @@ -17,4 +17,13 @@ name = "metacall" path = "src/lib.rs" [dependencies] -metacall-inline = { path = "./inline", version = "0.2.0" } +metacall-inline = { version = "0.2.0", path = "./inline" } + +[build-dependencies] +metacall-sys = { version = "0.1.2", path = "./sys" } + +[workspace] +members = [ + "inline", + "sys", +] diff --git a/source/ports/rs_port/LICENSE.txt b/source/ports/rs_port/LICENSE.txt index 2e591e57ad..d56ad81fad 100644 --- a/source/ports/rs_port/LICENSE.txt +++ b/source/ports/rs_port/LICENSE.txt @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2016-2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + 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. diff --git a/source/ports/rs_port/README.md b/source/ports/rs_port/README.md index 06f77ab060..1cce7dd4b9 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`](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 = "0.1.2" +``` + +`build.rs`: +```rust +fn main() { + // Find MetaCall library + metacall_sys::build(); +} +``` + # Example `sum.ts` @@ -26,14 +44,14 @@ 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(); + load::from_single_file(load::Tag::TypeScript, "sum.ts").unwrap(); // Call the sum function let sum = metacall::<f64>("sum", [1.0, 2.0]).unwrap(); diff --git a/source/ports/rs_port/build.rs b/source/ports/rs_port/build.rs index 4b7bcf3095..efb09e8f68 100644 --- a/source/ports/rs_port/build.rs +++ b/source/ports/rs_port/build.rs @@ -1,38 +1,4 @@ -use std::env; - 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 - 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") - } - _ => { - println!("cargo:rustc-link-lib=dylib=metacall") - } - } - } + // Find MetaCall library + metacall_sys::build(); } diff --git a/source/ports/rs_port/config.toml b/source/ports/rs_port/config.toml deleted file mode 100644 index f0d75af73f..0000000000 --- a/source/ports/rs_port/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[env] -CMAKE_BUILD_TYPE = { value = "Debug", force = true } -PROJECT_OUTPUT_DIR = { value = "/media/sf_koyanisqaatsi/metacall-core-rs-port-improved/build", force = true } diff --git a/source/ports/rs_port/inline/src/lib.rs b/source/ports/rs_port/inline/src/lib.rs index bb9358d5aa..0943868907 100644 --- a/source/ports/rs_port/inline/src/lib.rs +++ b/source/ports/rs_port/inline/src/lib.rs @@ -2,7 +2,7 @@ use proc_macro::TokenStream; use quote::quote; macro_rules! gen_inline_macro { - ($($name:ident),*) => ( + ($($name:ident => $tag:ident),*) => ( $( #[proc_macro] pub fn $name(input: TokenStream) -> TokenStream { @@ -10,7 +10,7 @@ macro_rules! gen_inline_macro { let buffer = token_stream_input.to_string(); let result = quote! {{ - ::metacall::load::from_memory(stringify!($name), #buffer.to_string()).unwrap() + ::metacall::load::from_memory(::metacall::load::Tag::$tag, #buffer.to_string(), None).unwrap() }}; result.into() @@ -19,4 +19,14 @@ macro_rules! gen_inline_macro { ) } -gen_inline_macro!(py, node, ts, cs, rb, cob, rpc, java, wasm); +gen_inline_macro!( + py => Python, + node => NodeJS, + ts => TypeScript, + cs => CSharp, + rb => Ruby, + cob => Cobol, + rpc => RPC, + java => Java, + wasm => Wasm +); diff --git a/source/ports/rs_port/src/bindings.rs b/source/ports/rs_port/src/bindings.rs index fdfc35049f..04c9be017c 100644 --- a/source/ports/rs_port/src/bindings.rs +++ b/source/ports/rs_port/src/bindings.rs @@ -65,6 +65,16 @@ const _: () = { [::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( @@ -80,6 +90,40 @@ 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 { @@ -627,13 +671,13 @@ unsafe extern "C" { ); } unsafe extern "C" { - #[doc = " @brief\n Unregister fork detours and destroy shared memory\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_fork_destroy() -> ::std::os::raw::c_int; + #[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: *mut ::std::os::raw::c_char, + pub tag: *const ::std::os::raw::c_char, pub options: *mut ::std::os::raw::c_void, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -703,6 +747,10 @@ 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(); @@ -1355,8 +1403,8 @@ unsafe extern "C" { pub fn metacall_plugin_path() -> *const ::std::os::raw::c_char; } unsafe extern "C" { - #[doc = " @brief\n Destroy MetaCall library\n\n @return\n Zero if success, different from zero otherwise"] - pub fn metacall_destroy() -> ::std::os::raw::c_int; + #[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"] diff --git a/source/ports/rs_port/src/cast.rs b/source/ports/rs_port/src/cast.rs index 51574fdf16..61e4c3e8c9 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/init.rs b/source/ports/rs_port/src/init.rs index da09899a24..fb578600ae 100644 --- a/source/ports/rs_port/src/init.rs +++ b/source/ports/rs_port/src/init.rs @@ -2,17 +2,13 @@ use crate::{ bindings::{metacall_destroy, metacall_initialize, metacall_is_initialized}, types::MetaCallInitError, }; -use std::{ffi::c_int, ptr}; +use std::ptr; -pub struct MetaCallDestroy(unsafe extern "C" fn() -> c_int); +pub struct MetaCallDestroy(unsafe extern "C" fn()); impl Drop for MetaCallDestroy { fn drop(&mut self) { - let code = unsafe { self.0() }; - - if code != 0 { - panic!("MetaCall failed to destroy with code: {}", code) - } + unsafe { self.0() } } } diff --git a/source/ports/rs_port/src/lib.rs b/source/ports/rs_port/src/lib.rs index 0f1f282a0c..678ba3fbf1 100644 --- a/source/ports/rs_port/src/lib.rs +++ b/source/ports/rs_port/src/lib.rs @@ -9,7 +9,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -41,15 +41,15 @@ //! 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) -//! load::from_single_file("ts", "sum.ts").unwrap(); +//! load::from_single_file(load::Tag::TypeScript, "sum.ts").unwrap(); //! //! // Call the sum function (Also checkout other metacall functions) //! let sum = metacall::<f64>("sum", [1.0, 2.0]).unwrap(); @@ -66,14 +66,14 @@ pub(crate) use macros::private_macros::*; /// Contains MetaCall loaders from file and memory. Usage example: ... /// ``` /// // Loading a single file with Nodejs. -/// metacall::load::from_single_file("node", "index.js").unwrap(); +/// metacall::load::from_single_file(metacall::load::Tag::NodeJS, "index.js").unwrap(); /// /// // Loading multiple files with Nodejs. -/// metacall::load::from_file("node", ["index.js", "main.js"]).unwrap(); +/// metacall::load::from_file(metacall::load::Tag::NodeJS, ["index.js", "main.js"]).unwrap(); /// /// // Loading a string with Nodejs. /// let script = "function greet() { return 'hi there!' }; module.exports = { greet };"; -/// metacall::load::from_memory("node", script).unwrap(); +/// metacall::load::from_memory(metacall::load::Tag::NodeJS, script, None).unwrap(); /// ``` pub mod load; @@ -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/load.rs b/source/ports/rs_port/src/load.rs index 4c9f8cc55b..290c7071d7 100644 --- a/source/ports/rs_port/src/load.rs +++ b/source/ports/rs_port/src/load.rs @@ -1,62 +1,157 @@ use crate::{ - bindings::{metacall_load_from_file, metacall_load_from_memory}, + bindings::{metacall_clear, metacall_load_from_file, metacall_load_from_memory}, cstring_enum, types::MetaCallLoaderError, }; use std::{ ffi::CString, + fmt, + os::raw::c_void, path::{Path, PathBuf}, - ptr, + ptr::null_mut, }; -/// Loads a script from a single file. Usage example: ... +pub enum Tag { + C, + Cobol, + Crystal, + CSharp, + Dart, + Deno, + Extension, + File, + Java, + Julia, + JavaScript, + JSM, + Kind, + LLVM, + Lua, + Mock, + NodeJS, + Python, + Ruby, + RPC, + Rust, + TypeScript, + Wasm, +} + +impl fmt::Display for Tag { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Tag::C => write!(f, "c"), + Tag::Cobol => write!(f, "cob"), + Tag::Crystal => write!(f, "cr"), + Tag::CSharp => write!(f, "cs"), + Tag::Dart => write!(f, "dart"), + Tag::Deno => write!(f, "deno"), + Tag::Extension => write!(f, "ext"), + Tag::File => write!(f, "file"), + Tag::Java => write!(f, "java"), + Tag::Julia => write!(f, "jl"), + Tag::JavaScript => write!(f, "js"), + Tag::JSM => write!(f, "jsm"), + Tag::Kind => write!(f, "kind"), + Tag::LLVM => write!(f, "llvm"), + Tag::Lua => write!(f, "lua"), + Tag::Mock => write!(f, "mock"), + Tag::NodeJS => write!(f, "node"), + Tag::Python => write!(f, "py"), + Tag::Ruby => write!(f, "rb"), + Tag::RPC => write!(f, "rpc"), + Tag::Rust => write!(f, "rs"), + Tag::TypeScript => write!(f, "ts"), + Tag::Wasm => write!(f, "wasm"), + } + } +} + +pub struct Handle(*mut c_void); + +impl Handle { + pub fn new() -> Self { + Self(null_mut()) + } + + pub fn as_mut_raw_ptr(&mut self) -> *mut c_void { + self.0 + } +} + +impl Default for Handle { + fn default() -> Self { + Self::new() + } +} + +impl Drop for Handle { + fn drop(&mut self) { + let result = unsafe { metacall_clear(self.0) }; + + if result != 0 { + // Log or handle the error as needed + eprintln!("Error during cleanup, metacall_clear returned: {}", result); + } + } +} + +/// Loads a file from a single file. Usage example: ... /// ``` -/// // A Nodejs script +/// // A Nodejs path /// metacall::load::from_single_file("node", "index.js").unwrap(); /// ``` pub fn from_single_file( - tag: impl ToString, - script: impl AsRef<Path>, + tag: Tag, + path: impl AsRef<Path>, + handle: Option<&mut Handle>, ) -> Result<(), MetaCallLoaderError> { - from_file(tag, [script]) + from_file(tag, [path], handle) } -/// Loads a script from file. Usage example: ... + +/// Loads a path from file. Usage example: ... /// ``` /// // A Nodejs script -/// metacall::load::from_file("node", ["index.js", "main.js"]).unwrap(); +/// metacall::load::from_file(Tag::NodeJS, ["index.js", "main.js"]).unwrap(); /// ``` pub fn from_file( - tag: impl ToString, - scripts: impl IntoIterator<Item = impl AsRef<Path>>, + tag: Tag, + paths: impl IntoIterator<Item = impl AsRef<Path>>, + handle: Option<&mut Handle>, ) -> Result<(), MetaCallLoaderError> { let c_tag = cstring_enum!(tag, MetaCallLoaderError)?; - let mut c_script: CString; + let mut c_path: CString; - let mut new_scripts: Vec<*const i8> = Vec::new(); - for script in scripts.into_iter() { - let script_as_pathbuf = PathBuf::from(script.as_ref()); - let script_as_str = script_as_pathbuf.to_str().unwrap(); + let mut new_paths: Vec<*const i8> = Vec::new(); + for path in paths.into_iter() { + let path_as_pathbuf = PathBuf::from(path.as_ref()); + let path_as_str = path_as_pathbuf.to_str().unwrap(); - if !script_as_pathbuf.exists() { - return Err(MetaCallLoaderError::FileNotFound(script_as_pathbuf)); + if !path_as_pathbuf.exists() { + return Err(MetaCallLoaderError::FileNotFound(path_as_pathbuf)); } - if !script_as_pathbuf.is_file() { + if !path_as_pathbuf.is_file() { return Err(MetaCallLoaderError::NotAFileOrPermissionDenied( - script_as_pathbuf, + path_as_pathbuf, )); } - c_script = cstring_enum!(script_as_str, MetaCallLoaderError)?; + c_path = cstring_enum!(path_as_str, MetaCallLoaderError)?; - new_scripts.push(c_script.as_ptr()); + new_paths.push(c_path.as_ptr()); } + let handle_ref = match handle { + Some(handle_ptr) => &mut handle_ptr.0, + None => null_mut(), + }; + if unsafe { metacall_load_from_file( c_tag.as_ptr(), - new_scripts.as_mut_ptr(), - new_scripts.len(), - ptr::null_mut(), + new_paths.as_mut_ptr(), + new_paths.len(), + handle_ref, ) } != 0 { @@ -71,19 +166,28 @@ pub fn from_file( /// let script = "function greet() { return 'hi there!' }; module.exports = { greet };"; /// /// // A Nodejs script -/// metacall::load::from_memory("node", script).unwrap(); +/// metacall::load::from_memory(Tag::NodeJS, script).unwrap(); /// ``` -pub fn from_memory(tag: impl ToString, script: impl ToString) -> Result<(), MetaCallLoaderError> { +pub fn from_memory( + tag: Tag, + script: impl ToString, + handle: Option<&mut Handle>, +) -> Result<(), MetaCallLoaderError> { let script = script.to_string(); let c_tag = cstring_enum!(tag, MetaCallLoaderError)?; let c_script = cstring_enum!(script, MetaCallLoaderError)?; + let handle_ref = match handle { + Some(handle_ptr) => &mut handle_ptr.0, + None => null_mut(), + }; + if unsafe { metacall_load_from_memory( c_tag.as_ptr(), c_script.as_ptr(), script.len() + 1, - ptr::null_mut(), + handle_ref, ) } != 0 { diff --git a/source/ports/rs_port/src/metacall.rs b/source/ports/rs_port/src/metacall.rs index f6e75c3072..7fe38a8bc7 100644 --- a/source/ports/rs_port/src/metacall.rs +++ b/source/ports/rs_port/src/metacall.rs @@ -1,6 +1,7 @@ use crate::{ - bindings::{metacall_function, metacall_value_destroy, metacallfv_s}, + bindings::{metacall_function, metacall_value_destroy, metacallfv_s, metacallhv_s}, cast, cstring_enum, + load::Handle, types::{MetaCallError, MetaCallNull, MetaCallValue}, }; use std::ffi::c_void; @@ -31,6 +32,33 @@ fn metacall_inner( Ok(ret) } + +fn metacall_inner_handle( + handle: &mut Handle, + func: impl ToString, + args: impl IntoIterator<Item = impl MetaCallValue>, +) -> Result<*mut c_void, MetaCallError> { + let c_function = cstring_enum!(func, MetaCallError)?; + + let mut c_args = cast::metacallobj_to_raw_args(args); + let args_length = c_args.len(); + + let ret = unsafe { + metacallhv_s( + handle.as_mut_raw_ptr(), + c_function.as_ptr(), + c_args.as_mut_ptr(), + args_length, + ) + }; + + for c_arg in c_args { + unsafe { metacall_value_destroy(c_arg) }; + } + + Ok(ret) +} + /// Calls a function same as [metacall](metacall) but returns a trait object /// of [MetaCallValue](MetaCallValue). This is useful when you don't know the return /// type of that function or the function may return multiple types. Checkout @@ -70,6 +98,24 @@ pub fn metacall<T: MetaCallValue>( Err(original) => Err(MetaCallError::FailedCasting(original)), } } + +/// Calls a function with arguments. The generic parameter is the return type of the function +/// you're calling. Checkout [MetaCallValue](MetaCallValue) for possible types. +/// For example: ... +/// ``` +/// let sum = metacall::metacall_handle::<i32>(handle, "sum", [1, 2]).unwrap(); +/// ``` +pub fn metacall_handle<T: MetaCallValue>( + handle: &mut Handle, + func: impl ToString, + args: impl IntoIterator<Item = impl MetaCallValue>, +) -> Result<T, MetaCallError> { + match cast::raw_to_metacallobj::<T>(metacall_inner_handle(handle, func, args)?) { + Ok(ret) => Ok(ret), + Err(original) => Err(MetaCallError::FailedCasting(original)), + } +} + /// Calls a function same as [metacall](metacall) without passing any arguments. For example: ... /// ``` /// let greet = metacall::metacall_no_arg::<String>("greet").unwrap(); @@ -77,3 +123,14 @@ pub fn metacall<T: MetaCallValue>( pub fn metacall_no_arg<T: MetaCallValue>(func: impl ToString) -> Result<T, MetaCallError> { metacall::<T>(func, [] as [MetaCallNull; 0]) } + +/// Calls a function same as [metacall](metacall) without passing any arguments. For example: ... +/// ``` +/// let greet = metacall::metacall_no_arg::<String>("greet").unwrap(); +/// ``` +pub fn metacall_handle_no_arg<T: MetaCallValue>( + handle: &mut Handle, + func: impl ToString, +) -> Result<T, MetaCallError> { + metacall_handle::<T>(handle, func, [] as [MetaCallNull; 0]) +} diff --git a/source/ports/rs_port/src/types/metacall_exception.rs b/source/ports/rs_port/src/types/metacall_exception.rs index c3bf662cc4..f753fce6ce 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_future.rs b/source/ports/rs_port/src/types/metacall_future.rs index de051d0d55..6caa25d532 100644 --- a/source/ports/rs_port/src/types/metacall_future.rs +++ b/source/ports/rs_port/src/types/metacall_future.rs @@ -19,7 +19,8 @@ use std::{ /// and the second argument is the data that you may want to access when the function gets called. /// Checkout [MetaCallFuture resolve](MetaCallFuture#method.then) or /// [MetaCallFuture reject](MetaCallFuture#method.catch) for usage. -pub type MetaCallFutureHandler = fn(Box<dyn MetaCallValue>, Box<dyn Any>) -> Box<dyn MetaCallValue>; +pub type MetaCallFutureHandler = + fn(Box<dyn MetaCallValue>, Option<Box<dyn Any>>) -> Box<dyn MetaCallValue>; /// Represents MetaCallFuture. Keep in mind that it's not supported to pass a future as an argument. /// @@ -118,7 +119,12 @@ type MetaCallFutureFFIData = ( unsafe extern "C" fn resolver(resolve_data: *mut c_void, upper_data: *mut c_void) -> *mut c_void { let (resolve, _, data) = *Box::from_raw(upper_data as *mut MetaCallFutureFFIData); - let user_data = Box::from_raw(data); + + let user_data = if !data.is_null() { + Some(Box::from_raw(data)) + } else { + None + }; let result = (resolve.unwrap())( cast::raw_to_metacallobj_untyped_leak(resolve_data), @@ -133,7 +139,12 @@ unsafe extern "C" fn resolver(resolve_data: *mut c_void, upper_data: *mut c_void } unsafe extern "C" fn rejecter(reject_data: *mut c_void, upper_data: *mut c_void) -> *mut c_void { let (_, reject, data) = *Box::from_raw(upper_data as *mut MetaCallFutureFFIData); - let user_data = Box::from_raw(data); + + let user_data = if !data.is_null() { + Some(Box::from_raw(data)) + } else { + None + }; let result = (reject.unwrap())( cast::raw_to_metacallobj_untyped_leak(reject_data), @@ -273,28 +284,6 @@ impl MetaCallFuture { None }, if reject_is_some { Some(rejecter) } else { None }, - // TODO: Solve the memory leak that happens here - // For reproducing the error, use the following commands: - // cargo test --no-run - // valgrind --trace-children=yes --leak-check=full --tool=memcheck --suppressions=../../../source/tests/memcheck/valgrind-node.supp ./target/debug/deps/metacall_test-248af33824f71bd1 &> output - // ==20664== 60 (32 direct, 28 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 35 - // ==20664== at 0x4842839: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) - // ==20664== by 0x17B549: alloc (alloc.rs:93) - // ==20664== by 0x17B549: alloc::alloc::Global::alloc_impl (alloc.rs:175) - // ==20664== by 0x17B342: allocate (alloc.rs:235) - // ==20664== by 0x17B342: alloc::alloc::exchange_malloc (alloc.rs:324) - // ==20664== by 0x1873D0: new<(core::option::Option<fn(alloc::boxed::Box<dyn metacall::types::metacall_value::MetaCallValue, alloc::alloc::Global>, alloc::boxed::Box<dyn metacall::types::metacall_value::MetaCallValue, alloc::alloc::Global>)>, core::option::Option<fn(alloc::boxed::Box<dyn metacall::types::metacall_value::MetaCallValue, alloc::alloc::Global>, alloc::boxed::Box<dyn metacall::types::metacall_value::MetaCallValue, alloc::alloc::Global>)>, *mut dyn metacall::types::metacall_value::MetaCallValue)> (boxed.rs:217) - // ==20664== by 0x1873D0: metacall::types::metacall_future::MetaCallFuture::await_fut (metacall_future.rs:182) - // ==20664== by 0x1296E6: metacall_test::test_future::{{closure}} (metacall_test.rs:202) - // ==20664== by 0x1286A2: metacall_test::generate_test_custom_validation (metacall_test.rs:42) - // ==20664== by 0x12625A: metacall_test::test_future (metacall_test.rs:193) - // ==20664== by 0x126954: metacall_test::metacall (metacall_test.rs:368) - // ==20664== by 0x129736: metacall_test::metacall::{{closure}} (metacall_test.rs:337) - // ==20664== by 0x1256B4: core::ops::function::FnOnce::call_once (function.rs:250) - // ==20664== by 0x166EBE: call_once<fn() -> core::result::Result<(), alloc::string::String>, ()> (function.rs:250) - // ==20664== by 0x166EBE: test::__rust_begin_short_backtrace (lib.rs:655) - // ==20664== by 0x13456B: {closure#1} (lib.rs:646) - // ==20664== by 0x13456B: core::ops::function::FnOnce::call_once{{vtable-shim}} (function.rs:250) Box::into_raw(Box::new((self.resolve, self.reject, self.data))) as *mut c_void, )) }; diff --git a/source/ports/rs_port/src/types/metacall_value.rs b/source/ports/rs_port/src/types/metacall_value.rs index 97a6695672..111dbd5908 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. @@ -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/sys/Cargo.toml b/source/ports/rs_port/sys/Cargo.toml new file mode 100644 index 0000000000..398dcaf52d --- /dev/null +++ b/source/ports/rs_port/sys/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "metacall-sys" +version = "0.1.2" +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 new file mode 100644 index 0000000000..f33176aafc --- /dev/null +++ b/source/ports/rs_port/sys/src/lib.rs @@ -0,0 +1,297 @@ +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) +} + +/// 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") { + // 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 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"; + + #[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/tests/inlines_test.rs b/source/ports/rs_port/tests/inlines_test.rs index ff5f483089..27861f2fb4 100644 --- a/source/ports/rs_port/tests/inlines_test.rs +++ b/source/ports/rs_port/tests/inlines_test.rs @@ -1,7 +1,8 @@ use metacall::{ initialize, inline::{node, py, ts}, - is_initialized, load, + is_initialized, + load::{self, Tag}, }; #[test] @@ -10,30 +11,30 @@ fn inlines() { assert!(is_initialized()); - if load::from_memory("py", "").is_ok() { + if load::from_memory(Tag::Python, "", None).is_ok() { py! { print("hello world") } } - if load::from_memory("py", "").is_ok() { + if load::from_memory(Tag::Python, "", None).is_ok() { py! {print("hello world")} } - if load::from_memory("node", "").is_ok() { + if load::from_memory(Tag::NodeJS, "", None).is_ok() { node! { console.log("hello world"); } } - if load::from_memory("node", "").is_ok() { + if load::from_memory(Tag::NodeJS, "", None).is_ok() { node! {console.log("hello world")} } - if load::from_memory("ts", "").is_ok() { + if load::from_memory(Tag::TypeScript, "", None).is_ok() { ts! { console.log("hello world"); } } - if load::from_memory("ts", "").is_ok() { + if load::from_memory(Tag::TypeScript, "", None).is_ok() { ts! {console.log("hello world")} } } diff --git a/source/ports/rs_port/tests/invalid_loaders_test.rs b/source/ports/rs_port/tests/invalid_loaders_test.rs index ec58d0bcb0..bd59e89a9b 100644 --- a/source/ports/rs_port/tests/invalid_loaders_test.rs +++ b/source/ports/rs_port/tests/invalid_loaders_test.rs @@ -1,4 +1,8 @@ -use metacall::{initialize, is_initialized, load, MetaCallLoaderError}; +use metacall::{ + initialize, is_initialized, + load::{self, Tag}, + MetaCallLoaderError, +}; use std::env; #[test] @@ -12,14 +16,16 @@ fn invalid_loaders() { let valid_file = scripts_dir.join("script.js"); if let Err(MetaCallLoaderError::FileNotFound(_)) = - load::from_single_file("random", inavlid_file) + load::from_single_file(load::Tag::NodeJS, inavlid_file, None) { // Everything Ok } else { panic!("Expected the loader fail with `FileNotFound` error variant!"); } - if let Err(MetaCallLoaderError::FromFileFailure) = load::from_single_file("random", valid_file) + // We use JSM here because it is not implemented, it should fail + if let Err(MetaCallLoaderError::FromFileFailure) = + load::from_single_file(Tag::JSM, valid_file, None) { // Everything Ok } else { @@ -27,7 +33,7 @@ fn invalid_loaders() { } if let Err(MetaCallLoaderError::FromMemoryFailure) = - load::from_memory("random", "Invalid code!") + load::from_memory(load::Tag::NodeJS, "Invalid code!", None) { // Everything Ok } else { diff --git a/source/ports/rs_port/tests/loaders_test.rs b/source/ports/rs_port/tests/loaders_test.rs index c45c4c17b9..abb274521a 100644 --- a/source/ports/rs_port/tests/loaders_test.rs +++ b/source/ports/rs_port/tests/loaders_test.rs @@ -1,4 +1,8 @@ -use metacall::{initialize, is_initialized, load, metacall_no_arg}; +use metacall::{ + initialize, is_initialized, + load::{self, Tag}, + metacall_no_arg, +}; use std::{ env, fs::{self, File}, @@ -11,16 +15,18 @@ use std::{ const SCRIPT1: &str = "function greet1() { return 'hi there!' } \nmodule.exports = { greet1 }"; const SCRIPT2: &str = "function greet2() { return 'hi there!' } \nmodule.exports = { greet2 };"; const SCRIPT3: &str = "console.log('Hello world')"; + fn call_greet(test: &str, num: u32) { let out = metacall_no_arg::<String>(format!("greet{}", num)).unwrap(); assert_eq!(out.as_str(), "hi there!", "Testing {}", test); } fn load_from_memory_test() { - load::from_memory("node", SCRIPT1).unwrap(); + load::from_memory(Tag::NodeJS, SCRIPT1, None).unwrap(); + call_greet("load_from_memory", 1); - load::from_memory("node", SCRIPT3).unwrap(); + load::from_memory(Tag::NodeJS, SCRIPT3, None).unwrap(); } fn load_from_file_test() { @@ -34,7 +40,7 @@ fn load_from_file_test() { temp_js.write_all(SCRIPT2.as_bytes()).unwrap(); temp_js.flush().unwrap(); - load::from_single_file("node", temp_js_path).unwrap(); + load::from_single_file(Tag::NodeJS, temp_js_path, None).unwrap(); call_greet("load_from_file", 2); diff --git a/source/ports/rs_port/tests/metacall_exception_test.rs b/source/ports/rs_port/tests/metacall_exception_test.rs index 780aba0562..fe16caad70 100644 --- a/source/ports/rs_port/tests/metacall_exception_test.rs +++ b/source/ports/rs_port/tests/metacall_exception_test.rs @@ -1,8 +1,11 @@ -use metacall::{initialize, is_initialized, load}; +use metacall::{ + initialize, is_initialized, + load::{self, Tag}, +}; use std::env; #[test] -fn inlines() { +fn metacall_exception() { let _d = initialize().unwrap(); assert!(is_initialized()); @@ -10,7 +13,7 @@ fn inlines() { let tests_dir = env::current_dir().unwrap().join("tests/scripts"); let js_test_file = tests_dir.join("script.js"); - if load::from_single_file("node", js_test_file).is_ok() { + if load::from_single_file(Tag::NodeJS, js_test_file, None).is_ok() { // This should not generate a segmentation fault let val = metacall::metacall_no_arg::<metacall::MetaCallException>("test_exception").unwrap(); diff --git a/source/ports/rs_port/tests/metacall_handle_test.rs b/source/ports/rs_port/tests/metacall_handle_test.rs new file mode 100644 index 0000000000..516d5b52f0 --- /dev/null +++ b/source/ports/rs_port/tests/metacall_handle_test.rs @@ -0,0 +1,52 @@ +use metacall::{ + initialize, is_initialized, + load::{self, Handle, Tag}, + metacall_handle_no_arg, +}; + +#[test] +fn metacall_handle() { + let _d = initialize().unwrap(); + + assert!(is_initialized()); + + const SCRIPT1: &str = "function greet() { return 1 } \nmodule.exports = { greet }"; + const SCRIPT2: &str = "function greet() { return 2 } \nmodule.exports = { greet }"; + + let mut handle1 = Handle::new(); + let mut handle2 = Handle::new(); + + let result1 = load::from_memory(Tag::NodeJS, SCRIPT1, Some(&mut handle1)); + let result2 = load::from_memory(Tag::NodeJS, SCRIPT2, Some(&mut handle2)); + + assert!(result1.is_ok()); + assert!(result2.is_ok()); + + // Load first handle + if result1.is_ok() { + let out = metacall_handle_no_arg::<f64>(&mut handle1, "greet").unwrap(); + assert_eq!(out, 1.0, "Testing greet 1"); + } + + // Load second handle + if result2.is_ok() { + let out = metacall_handle_no_arg::<f64>(&mut handle2, "greet").unwrap(); + assert_eq!(out, 2.0, "Testing greet 2"); + } + + // Now, testing loading again into an existing handle number 2 + // This should make the handle have greet (2) and yeet functions together + const SCRIPT3: &str = "function yeet() { return 3 } \nmodule.exports = { yeet }"; + + let result3 = load::from_memory(Tag::NodeJS, SCRIPT3, Some(&mut handle2)); + + assert!(result3.is_ok()); + + if result3.is_ok() { + let out = metacall_handle_no_arg::<f64>(&mut handle2, "greet").unwrap(); + assert_eq!(out, 2.0, "Testing greet 2"); + + let out = metacall_handle_no_arg::<f64>(&mut handle2, "yeet").unwrap(); + assert_eq!(out, 3.0, "Testing yeet 2"); + } +} diff --git a/source/ports/rs_port/tests/metacall_test.rs b/source/ports/rs_port/tests/metacall_test.rs index ad6389262c..81d73511a3 100644 --- a/source/ports/rs_port/tests/metacall_test.rs +++ b/source/ports/rs_port/tests/metacall_test.rs @@ -1,7 +1,8 @@ use metacall::{ - initialize, is_initialized, load, MetaCallClass, MetaCallException, MetaCallFunction, - MetaCallFuture, MetaCallNull, MetaCallObject, MetaCallPointer, MetaCallThrowable, - MetaCallValue, + initialize, is_initialized, + load::{self, Tag}, + MetaCallClass, MetaCallException, MetaCallFunction, MetaCallFuture, MetaCallNull, + MetaCallObject, MetaCallPointer, MetaCallThrowable, MetaCallValue, }; use std::{any::Any, collections::HashMap, env, fmt::Debug}; @@ -81,27 +82,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", @@ -176,16 +172,19 @@ fn test_pointer() { ); } fn test_future() { - fn validate(upper_result: Box<dyn MetaCallValue>, upper_data: Box<dyn Any>) { - match upper_data.downcast::<String>() { - Ok(ret) => { - if ret.as_str() != "data" { - invalid_return_value("data", ret) + fn validate(upper_result: Box<dyn MetaCallValue>, upper_data: Option<Box<dyn Any>>) { + match upper_data { + Some(data) => match data.downcast::<String>() { + Ok(ret) => { + if ret.as_str() != "data" { + invalid_return_value("data", ret) + } } - } - Err(original) => { - invalid_return_type("'string' for the data", original); - } + Err(original) => { + invalid_return_type("'string' for the data", original); + } + }, + None => println!("user_data is None."), } match upper_result.downcast::<String>() { @@ -207,7 +206,7 @@ fn test_future() { move |future| { fn resolve( result: Box<dyn MetaCallValue>, - data: Box<dyn Any>, + data: Option<Box<dyn Any>>, ) -> Box<dyn MetaCallValue> { validate(result.clone(), data); result.clone() @@ -223,7 +222,7 @@ fn test_future() { move |future| { fn reject( result: Box<dyn MetaCallValue>, - data: Box<dyn Any>, + data: Option<Box<dyn Any>>, ) -> Box<dyn MetaCallValue> { validate(result.clone(), data); result.clone() @@ -373,7 +372,7 @@ fn metacall() { let js_test_file = tests_dir.join("script.js"); let c_test_file = tests_dir.join("script.c"); let py_test_file = tests_dir.join("script.py"); - let py_loaded = load::from_single_file("py", py_test_file).is_ok(); + let py_loaded = load::from_single_file(Tag::Python, py_test_file, None).is_ok(); if py_loaded { test_buffer(); @@ -386,17 +385,16 @@ fn metacall() { test_string(); test_null(); } - if load::from_single_file("c", c_test_file).is_ok() { + if load::from_single_file(load::Tag::C, c_test_file, None).is_ok() { test_char(); test_double(); test_float(); test_int(); test_long(); test_short(); - // TODO - // test_mixed_numbers(); + test_mixed_numbers(); } - if load::from_single_file("node", js_test_file).is_ok() { + if load::from_single_file(load::Tag::NodeJS, js_test_file, None).is_ok() { test_exception(); test_throwable(); test_future(); diff --git a/source/ports/rs_port/upload.sh b/source/ports/rs_port/upload.sh index a081a7037a..a072d2c657 100644 --- a/source/ports/rs_port/upload.sh +++ b/source/ports/rs_port/upload.sh @@ -4,7 +4,7 @@ # MetaCall Rust Port Deploy Script by Parra Studios # Script utility for deploying MetaCall Rust Port to Crates. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -21,7 +21,7 @@ function publish() { local crate_version=`cargo search --quiet $1 | grep "$1" | head -n 1 | awk '{ print $3 }'` - local project_version=`cargo metadata --format-version=1 --no-deps | jq '.packages[0].version'` + local project_version=`cargo metadata --format-version=1 --no-deps | jq ".packages[] | select(.name == \"$1\") | .version"` # Check if versions do not match, and if so, publish them if [ ! "${crate_version}" = "${project_version}" ]; then @@ -30,8 +30,15 @@ function publish() { fi } -# Publish -cd inline +# Publish sys crate +pushd sys +publish metacall-sys +popd + +# Publish inline crate +pushd inline publish metacall-inline -cd .. +popd + +# Publish metacall crate publish metacall diff --git a/source/ports/zig_port/src/metacall-bindings.zig b/source/ports/zig_port/src/metacall-bindings.zig index 05243d2426..9e51c89cd2 100644 --- a/source/ports/zig_port/src/metacall-bindings.zig +++ b/source/ports/zig_port/src/metacall-bindings.zig @@ -1235,7 +1235,7 @@ pub const metacall_pre_fork_callback_ptr = ?*const fn (?*anyopaque) callconv(.C) pub const metacall_post_fork_callback_ptr = ?*const fn (metacall_pid, ?*anyopaque) callconv(.C) c_int; pub extern fn metacall_fork_initialize() c_int; pub extern fn metacall_fork(pre_callback: metacall_pre_fork_callback_ptr, post_callback: metacall_post_fork_callback_ptr) void; -pub extern fn metacall_fork_destroy() c_int; +pub extern fn metacall_fork_destroy() void; pub const struct_metacall_initialize_configuration_type = extern struct { tag: [*c]u8 = @import("std").mem.zeroes([*c]u8), options: ?*anyopaque = @import("std").mem.zeroes(?*anyopaque), @@ -1325,7 +1325,7 @@ pub extern fn metacall_deserialize(name: [*c]const u8, buffer: [*c]const u8, siz pub extern fn metacall_clear(handle: ?*anyopaque) c_int; pub extern fn metacall_plugin_extension() ?*anyopaque; pub extern fn metacall_plugin_path() [*c]const u8; -pub extern fn metacall_destroy() c_int; +pub extern fn metacall_destroy() void; pub extern fn metacall_version() [*c]const struct_metacall_version_type; pub extern fn metacall_version_hex_make(major: c_uint, minor: c_uint, patch: c_uint) u32; pub extern fn metacall_version_hex() u32; diff --git a/source/ports/zig_port/src/root.zig b/source/ports/zig_port/src/root.zig index bb88c3da0e..6bc5054e08 100644 --- a/source/ports/zig_port/src/root.zig +++ b/source/ports/zig_port/src/root.zig @@ -9,13 +9,8 @@ pub fn init() !void { return error.FailedToInitMetacall; } /// Deinitializes MetaCall and returns an error if didn't succeed. -pub fn destroy() !void { - if (mb.metacall_destroy() != 0) - return error.FailedToDeinitMetacall; -} -/// Deinitializes MetaCall. -pub fn deinit() void { - _ = destroy() catch {}; +pub fn destroy() void { + mb.metacall_destroy(); } /// Loads files into MetaCall, strings should be null-terminated. diff --git a/source/ports/zig_port/src/tests/integrated.zig b/source/ports/zig_port/src/tests/integrated.zig index 8ee7089f3a..70b46b7985 100644 --- a/source/ports/zig_port/src/tests/integrated.zig +++ b/source/ports/zig_port/src/tests/integrated.zig @@ -38,5 +38,5 @@ pub fn main() !void { try std.testing.expect(ret_string.?[0] == 'h'); try std.testing.expect(ret_string.?[1] == 'i'); - defer metacall.deinit(); + defer metacall.destroy(); } diff --git a/source/preprocessor/CMakeLists.txt b/source/preprocessor/CMakeLists.txt index da28c94b71..a850683fc9 100644 --- a/source/preprocessor/CMakeLists.txt +++ b/source/preprocessor/CMakeLists.txt @@ -179,7 +179,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/preprocessor/cmake/preprocessor_arguments.cmake b/source/preprocessor/cmake/preprocessor_arguments.cmake index 38014c9b8c..fa35626a3f 100644 --- a/source/preprocessor/cmake/preprocessor_arguments.cmake +++ b/source/preprocessor/cmake/preprocessor_arguments.cmake @@ -2,7 +2,7 @@ # Preprocessor Library by Parra Studios # A generic header-only preprocessor metaprogramming library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/preprocessor/cmake/preprocessor_arguments_body.h.in b/source/preprocessor/cmake/preprocessor_arguments_body.h.in index 86d6d511f1..bad23f8792 100644 --- a/source/preprocessor/cmake/preprocessor_arguments_body.h.in +++ b/source/preprocessor/cmake/preprocessor_arguments_body.h.in @@ -47,7 +47,7 @@ PREPROCESSOR_ARGS_COMMA(PREPROCESSOR_COMMA_VARIADIC __VA_ARGS__ ()) \ ) -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_ARGS_COUNT_IMPL(...) \ PREPROCESSOR_ARGS_N_IMPL(__VA_ARGS__) # define PREPROCESSOR_ARGS_COUNT(...) \ @@ -70,7 +70,7 @@ # define PREPROCESSOR_ARGS_COMMA(...) \ PREPROCESSOR_ARGS_COUNT_IMPL(__VA_ARGS__, PREPROCESSOR_ARGS_COMMA_SEQ_IMPL()) # endif -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_ARGS_COUNT_PREFIX__PREPROCESSOR_ARGS_COUNT_POSTFIX @PREPROCESSOR_ARGS_COUNT_PREFIX_POSTFIX_BODY@0 # define PREPROCESSOR_ARGS_COUNT_IMPL(expr) PREPROCESSOR_ARGS_N_IMPL expr # define PREPROCESSOR_ARGS_COUNT(...) \ diff --git a/source/preprocessor/cmake/preprocessor_arithmetic.cmake b/source/preprocessor/cmake/preprocessor_arithmetic.cmake index eca9525db6..3c3b33f6b5 100644 --- a/source/preprocessor/cmake/preprocessor_arithmetic.cmake +++ b/source/preprocessor/cmake/preprocessor_arithmetic.cmake @@ -2,7 +2,7 @@ # Preprocessor Library by Parra Studios # A generic header-only preprocessor metaprogramming library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/preprocessor/cmake/preprocessor_boolean.cmake b/source/preprocessor/cmake/preprocessor_boolean.cmake index 444336b646..f4dda84e0b 100644 --- a/source/preprocessor/cmake/preprocessor_boolean.cmake +++ b/source/preprocessor/cmake/preprocessor_boolean.cmake @@ -2,7 +2,7 @@ # Preprocessor Library by Parra Studios # A generic header-only preprocessor metaprogramming library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/preprocessor/cmake/preprocessor_for.cmake b/source/preprocessor/cmake/preprocessor_for.cmake index abded5af57..883276b6ed 100644 --- a/source/preprocessor/cmake/preprocessor_for.cmake +++ b/source/preprocessor/cmake/preprocessor_for.cmake @@ -2,7 +2,7 @@ # Preprocessor Library by Parra Studios # A generic header-only preprocessor metaprogramming library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/preprocessor/cmake/preprocessor_for_body.h.in b/source/preprocessor/cmake/preprocessor_for_body.h.in index 57e9977b58..a175100f31 100644 --- a/source/preprocessor/cmake/preprocessor_for_body.h.in +++ b/source/preprocessor/cmake/preprocessor_for_body.h.in @@ -18,14 +18,14 @@ expr(element) PREPROCESSOR_FOR_EACH_EVAL(PREPROCESSOR_FOR_EACH_IMPL_1(expr, __VA_ARGS__)) #endif @PREPROCESSOR_FOR_EACH_IMPL_BODY@ -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_FOR_EACH(expr, ...) \ PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), \ PREPROCESSOR_EMPTY_SYMBOL(), \ PREPROCESSOR_ARGS_N_IMPL(__VA_ARGS__, \ @PREPROCESSOR_FOR_EACH_IMPL_GNUC_BODY@\ PREPROCESSOR_FOR_EACH_IMPL_0)(expr, __VA_ARGS__)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_FOR_EACH_IMPL_COUNT(count) \ PREPROCESSOR_CONCAT(PREPROCESSOR_FOR_EACH_IMPL_, count) # define PREPROCESSOR_FOR_EACH_IMPL_EXPR(...) \ @@ -57,14 +57,14 @@ expr(context, iterator, element) PREPROCESSOR_FOR_EVAL(PREPROCESSOR_FOR_IMPL_1(expr, context, PREPROCESSOR_INCREMENT(iterator), __VA_ARGS__)) #endif @PREPROCESSOR_FOR_IMPL_BODY@ -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_FOR(expr, context, ...) \ PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), \ PREPROCESSOR_EMPTY_SYMBOL(), \ PREPROCESSOR_ARGS_N_IMPL(__VA_ARGS__, \ @PREPROCESSOR_FOR_IMPL_GNUC_BODY@\ PREPROCESSOR_FOR_IMPL_0)(expr, context, 0, __VA_ARGS__)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_FOR_IMPL_COUNT(count) \ PREPROCESSOR_CONCAT(PREPROCESSOR_FOR_IMPL_, count) # define PREPROCESSOR_FOR_IMPL_EXPR(...) \ diff --git a/source/preprocessor/cmake/preprocessor_template.cmake b/source/preprocessor/cmake/preprocessor_template.cmake index 11d99a682b..782e5b07c9 100644 --- a/source/preprocessor/cmake/preprocessor_template.cmake +++ b/source/preprocessor/cmake/preprocessor_template.cmake @@ -2,7 +2,7 @@ # Preprocessor Library by Parra Studios # A generic header-only preprocessor metaprogramming library. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/preprocessor/cmake/preprocessor_template.h.in b/source/preprocessor/cmake/preprocessor_template.h.in index 41b0d1825d..59c5270672 100644 --- a/source/preprocessor/cmake/preprocessor_template.h.in +++ b/source/preprocessor/cmake/preprocessor_template.h.in @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/include/preprocessor/preprocessor.h b/source/preprocessor/include/preprocessor/preprocessor.h index e223cf40f4..62c66cbcfb 100644 --- a/source/preprocessor/include/preprocessor/preprocessor.h +++ b/source/preprocessor/include/preprocessor/preprocessor.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/include/preprocessor/preprocessor_arguments.h b/source/preprocessor/include/preprocessor/preprocessor_arguments.h index 2f114d9132..b02fc1dbd0 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_arguments.h +++ b/source/preprocessor/include/preprocessor/preprocessor_arguments.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -104,7 +104,7 @@ extern "C" { PREPROCESSOR_ARGS_COMMA(PREPROCESSOR_COMMA_VARIADIC __VA_ARGS__ ()) \ ) -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_ARGS_COUNT_IMPL(...) \ PREPROCESSOR_ARGS_N_IMPL(__VA_ARGS__) # define PREPROCESSOR_ARGS_COUNT(...) \ @@ -190,7 +190,7 @@ extern "C" { # define PREPROCESSOR_ARGS_COMMA(...) \ PREPROCESSOR_ARGS_COUNT_IMPL(__VA_ARGS__, PREPROCESSOR_ARGS_COMMA_SEQ_IMPL()) # endif -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_ARGS_COUNT_PREFIX__PREPROCESSOR_ARGS_COUNT_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0 # define PREPROCESSOR_ARGS_COUNT_IMPL(expr) PREPROCESSOR_ARGS_N_IMPL expr # define PREPROCESSOR_ARGS_COUNT(...) \ diff --git a/source/preprocessor/include/preprocessor/preprocessor_arithmetic.h b/source/preprocessor/include/preprocessor/preprocessor_arithmetic.h index b1a9c96479..6b7974ba43 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_arithmetic.h +++ b/source/preprocessor/include/preprocessor/preprocessor_arithmetic.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/include/preprocessor/preprocessor_bit.h b/source/preprocessor/include/preprocessor/preprocessor_bit.h index f2aee9d4de..952078a2a0 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_bit.h +++ b/source/preprocessor/include/preprocessor/preprocessor_bit.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * diff --git a/source/preprocessor/include/preprocessor/preprocessor_boolean.h b/source/preprocessor/include/preprocessor/preprocessor_boolean.h index e042d9ff5e..3cb26ad412 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_boolean.h +++ b/source/preprocessor/include/preprocessor/preprocessor_boolean.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/include/preprocessor/preprocessor_comma.h b/source/preprocessor/include/preprocessor/preprocessor_comma.h index 62ce258cc8..cf4a4b972a 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_comma.h +++ b/source/preprocessor/include/preprocessor/preprocessor_comma.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/include/preprocessor/preprocessor_comparison.h b/source/preprocessor/include/preprocessor/preprocessor_comparison.h index b4839e1246..5308f0699e 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_comparison.h +++ b/source/preprocessor/include/preprocessor/preprocessor_comparison.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * diff --git a/source/preprocessor/include/preprocessor/preprocessor_complement.h b/source/preprocessor/include/preprocessor/preprocessor_complement.h index a7300fc45a..0cd0b5f02e 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_complement.h +++ b/source/preprocessor/include/preprocessor/preprocessor_complement.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * @@ -24,7 +24,7 @@ extern "C" { /* -- Macros -- */ -#if defined(_MSC_VER) && !defined(__clang__) +#if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_COMPL_IMPL_EXPAND(expr) expr #define PREPROCESSOR_COMPL_IMPL(expr) PREPROCESSOR_COMPL_IMPL_EXPAND(PREPROCESSOR_COMPL_IMPL_##expr) #else diff --git a/source/preprocessor/include/preprocessor/preprocessor_concatenation.h b/source/preprocessor/include/preprocessor/preprocessor_concatenation.h index f54986f00b..e5d3c79581 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_concatenation.h +++ b/source/preprocessor/include/preprocessor/preprocessor_concatenation.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * @@ -19,7 +19,7 @@ extern "C" { /* -- Macros -- */ -#if defined(_MSC_VER) && !defined(__clang__) +#if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_CONCAT_IMPL_II(token, expr) expr #define PREPROCESSOR_CONCAT_IMPL_I(left, right) PREPROCESSOR_CONCAT_IMPL_II(~, left##right) #define PREPROCESSOR_CONCAT_IMPL(left, right) PREPROCESSOR_CONCAT_IMPL_I(left, right) diff --git a/source/preprocessor/include/preprocessor/preprocessor_detection.h b/source/preprocessor/include/preprocessor/preprocessor_detection.h index 6306765067..d64e511347 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_detection.h +++ b/source/preprocessor/include/preprocessor/preprocessor_detection.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * diff --git a/source/preprocessor/include/preprocessor/preprocessor_empty.h b/source/preprocessor/include/preprocessor/preprocessor_empty.h index 0ce59a48cd..91f774f9a4 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_empty.h +++ b/source/preprocessor/include/preprocessor/preprocessor_empty.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * diff --git a/source/preprocessor/include/preprocessor/preprocessor_for.h b/source/preprocessor/include/preprocessor/preprocessor_for.h index b391df429b..530dc8ee1f 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_for.h +++ b/source/preprocessor/include/preprocessor/preprocessor_for.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -115,7 +115,7 @@ extern "C" { #define PREPROCESSOR_FOR_EACH_IMPL_63(expr, element, ...) expr(element) PREPROCESSOR_FOR_EACH_EVAL(PREPROCESSOR_FOR_EACH_IMPL_62(expr, __VA_ARGS__)) #define PREPROCESSOR_FOR_EACH_IMPL_64(expr, element, ...) expr(element) PREPROCESSOR_FOR_EACH_EVAL(PREPROCESSOR_FOR_EACH_IMPL_63(expr, __VA_ARGS__)) -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_FOR_EACH(expr, ...) \ PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), \ PREPROCESSOR_EMPTY_SYMBOL(), \ @@ -128,7 +128,7 @@ extern "C" { PREPROCESSOR_FOR_EACH_IMPL_19, PREPROCESSOR_FOR_EACH_IMPL_18, PREPROCESSOR_FOR_EACH_IMPL_17, PREPROCESSOR_FOR_EACH_IMPL_16, PREPROCESSOR_FOR_EACH_IMPL_15, PREPROCESSOR_FOR_EACH_IMPL_14, PREPROCESSOR_FOR_EACH_IMPL_13, PREPROCESSOR_FOR_EACH_IMPL_12, PREPROCESSOR_FOR_EACH_IMPL_11, PREPROCESSOR_FOR_EACH_IMPL_10, \ PREPROCESSOR_FOR_EACH_IMPL_9, PREPROCESSOR_FOR_EACH_IMPL_8, PREPROCESSOR_FOR_EACH_IMPL_7, PREPROCESSOR_FOR_EACH_IMPL_6, PREPROCESSOR_FOR_EACH_IMPL_5, PREPROCESSOR_FOR_EACH_IMPL_4, PREPROCESSOR_FOR_EACH_IMPL_3, PREPROCESSOR_FOR_EACH_IMPL_2, PREPROCESSOR_FOR_EACH_IMPL_1, \ PREPROCESSOR_FOR_EACH_IMPL_0)(expr, __VA_ARGS__)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_FOR_EACH_IMPL_COUNT(count) \ PREPROCESSOR_CONCAT(PREPROCESSOR_FOR_EACH_IMPL_, count) # define PREPROCESSOR_FOR_EACH_IMPL_EXPR(...) \ @@ -222,7 +222,7 @@ extern "C" { #define PREPROCESSOR_FOR_IMPL_63(expr, context, iterator, element, ...) expr(context, iterator, element) PREPROCESSOR_FOR_EVAL(PREPROCESSOR_FOR_IMPL_62(expr, context, PREPROCESSOR_INCREMENT(iterator), __VA_ARGS__)) #define PREPROCESSOR_FOR_IMPL_64(expr, context, iterator, element, ...) expr(context, iterator, element) PREPROCESSOR_FOR_EVAL(PREPROCESSOR_FOR_IMPL_63(expr, context, PREPROCESSOR_INCREMENT(iterator), __VA_ARGS__)) -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && !(!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) # define PREPROCESSOR_FOR(expr, context, ...) \ PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), \ PREPROCESSOR_EMPTY_SYMBOL(), \ @@ -235,7 +235,7 @@ extern "C" { PREPROCESSOR_FOR_IMPL_19, PREPROCESSOR_FOR_IMPL_18, PREPROCESSOR_FOR_IMPL_17, PREPROCESSOR_FOR_IMPL_16, PREPROCESSOR_FOR_IMPL_15, PREPROCESSOR_FOR_IMPL_14, PREPROCESSOR_FOR_IMPL_13, PREPROCESSOR_FOR_IMPL_12, PREPROCESSOR_FOR_IMPL_11, PREPROCESSOR_FOR_IMPL_10, \ PREPROCESSOR_FOR_IMPL_9, PREPROCESSOR_FOR_IMPL_8, PREPROCESSOR_FOR_IMPL_7, PREPROCESSOR_FOR_IMPL_6, PREPROCESSOR_FOR_IMPL_5, PREPROCESSOR_FOR_IMPL_4, PREPROCESSOR_FOR_IMPL_3, PREPROCESSOR_FOR_IMPL_2, PREPROCESSOR_FOR_IMPL_1, \ PREPROCESSOR_FOR_IMPL_0)(expr, context, 0, __VA_ARGS__)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) # define PREPROCESSOR_FOR_IMPL_COUNT(count) \ PREPROCESSOR_CONCAT(PREPROCESSOR_FOR_IMPL_, count) # define PREPROCESSOR_FOR_IMPL_EXPR(...) \ diff --git a/source/preprocessor/include/preprocessor/preprocessor_if.h b/source/preprocessor/include/preprocessor/preprocessor_if.h index 622397e892..513df26cf1 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_if.h +++ b/source/preprocessor/include/preprocessor/preprocessor_if.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * @@ -33,7 +33,7 @@ extern "C" { #define PREPROCESSOR_IIF_IMPL_1(true_expr, false_expr) true_expr #endif -#if defined(_MSC_VER) && !defined(__clang__) +#if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_IIF_IMPL_I(expr) expr #define PREPROCESSOR_IIF_IMPL(value, true_expr, false_expr) PREPROCESSOR_IIF_IMPL_I(PREPROCESSOR_IIF_IMPL_##value(true_expr, false_expr)) #else diff --git a/source/preprocessor/include/preprocessor/preprocessor_serial.h b/source/preprocessor/include/preprocessor/preprocessor_serial.h index b4e222c1a8..6b64c2d7c4 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_serial.h +++ b/source/preprocessor/include/preprocessor/preprocessor_serial.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * diff --git a/source/preprocessor/include/preprocessor/preprocessor_stringify.h b/source/preprocessor/include/preprocessor/preprocessor_stringify.h index 322b2806a2..fb84478d93 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_stringify.h +++ b/source/preprocessor/include/preprocessor/preprocessor_stringify.h @@ -1,6 +1,6 @@ /* * Preprocessor Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A generic header-only preprocessor metaprogramming library. * @@ -27,7 +27,7 @@ extern "C" { #if defined(__MWERKS__) #define PREPROCESSOR_STRINGIFY_IMPL_I(tuple) PREPROCESSOR_STRINGIFY_IMPL##tuple #define PREPROCESSOR_STRINGIFY(expr) PREPROCESSOR_STRINGIFY_IMPL_I((expr)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_STRINGIFY_IMPL_I(tuple) PREPROCESSOR_STRINGIFY_IMPL tuple #define PREPROCESSOR_STRINGIFY(expr) PREPROCESSOR_STRINGIFY_IMPL_I((expr)) #else @@ -35,7 +35,7 @@ extern "C" { #endif /* Stringify a symbol or return empty string if the expression expands to nothing */ -#if defined(_MSC_VER) && !defined(__clang__) +#if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL_II(...) #__VA_ARGS__ #define PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL(...) \ PREPROCESSOR_IF(PREPROCESSOR_ARGS_NOT_EMPTY(__VA_ARGS__), \ @@ -48,7 +48,7 @@ extern "C" { #if defined(__MWERKS__) #define PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL_I(tuple) PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL##tuple #define PREPROCESSOR_STRINGIFY_OR_EMPTY(expr) PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL_I((expr)) -#elif defined(_MSC_VER) && !defined(__clang__) +#elif (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) && !defined(__clang__) #define PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL_I(tuple) PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL tuple #define PREPROCESSOR_STRINGIFY_OR_EMPTY(expr) PREPROCESSOR_STRINGIFY_OR_EMPTY_IMPL_I((expr)) #else diff --git a/source/preprocessor/include/preprocessor/preprocessor_tuple.h b/source/preprocessor/include/preprocessor/preprocessor_tuple.h index 817ecd3bfa..1c8ba1eadb 100644 --- a/source/preprocessor/include/preprocessor/preprocessor_tuple.h +++ b/source/preprocessor/include/preprocessor/preprocessor_tuple.h @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/preprocessor/source/preprocessor.c b/source/preprocessor/source/preprocessor.c index e6730f45c9..d9124af879 100644 --- a/source/preprocessor/source/preprocessor.c +++ b/source/preprocessor/source/preprocessor.c @@ -2,7 +2,7 @@ * Preprocessor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -30,7 +30,7 @@ const char *preprocessor_print_info(void) { static const char preprocessor_info[] = "Preprocessor Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef PREPROCSSOR_STATIC_DEFINE "Compiled as static library type" diff --git a/source/reflect/CMakeLists.txt b/source/reflect/CMakeLists.txt index ed13aa98bd..0131e04534 100644 --- a/source/reflect/CMakeLists.txt +++ b/source/reflect/CMakeLists.txt @@ -203,7 +203,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/reflect/include/reflect/reflect.h b/source/reflect/include/reflect/reflect.h index 469e1b8c59..967df3bafb 100644 --- a/source/reflect/include/reflect/reflect.h +++ b/source/reflect/include/reflect/reflect.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_accessor.h b/source/reflect/include/reflect/reflect_accessor.h index 0dd824051e..8b6b7db349 100644 --- a/source/reflect/include/reflect/reflect_accessor.h +++ b/source/reflect/include/reflect/reflect_accessor.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_async.h b/source/reflect/include/reflect/reflect_async.h index 0ce7ed4236..09b9a2e59c 100644 --- a/source/reflect/include/reflect/reflect_async.h +++ b/source/reflect/include/reflect/reflect_async.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_attribute.h b/source/reflect/include/reflect/reflect_attribute.h index 72c1ecdae4..0a628a30c6 100644 --- a/source/reflect/include/reflect/reflect_attribute.h +++ b/source/reflect/include/reflect/reflect_attribute.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_attribute_decl.h b/source/reflect/include/reflect/reflect_attribute_decl.h index d3bb74370d..61bc8dffb0 100644 --- a/source/reflect/include/reflect/reflect_attribute_decl.h +++ b/source/reflect/include/reflect/reflect_attribute_decl.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_class.h b/source/reflect/include/reflect/reflect_class.h index 5056602f0e..16aa01f36d 100644 --- a/source/reflect/include/reflect/reflect_class.h +++ b/source/reflect/include/reflect/reflect_class.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_class_decl.h b/source/reflect/include/reflect/reflect_class_decl.h index 44c739433a..4252569d79 100644 --- a/source/reflect/include/reflect/reflect_class_decl.h +++ b/source/reflect/include/reflect/reflect_class_decl.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_class_visibility.h b/source/reflect/include/reflect/reflect_class_visibility.h index c5641a28a2..5a557782df 100644 --- a/source/reflect/include/reflect/reflect_class_visibility.h +++ b/source/reflect/include/reflect/reflect_class_visibility.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_constructor.h b/source/reflect/include/reflect/reflect_constructor.h index cfccebdf0c..d0fc0de022 100644 --- a/source/reflect/include/reflect/reflect_constructor.h +++ b/source/reflect/include/reflect/reflect_constructor.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_constructor_decl.h b/source/reflect/include/reflect/reflect_constructor_decl.h index 54ebace012..74565b45bc 100644 --- a/source/reflect/include/reflect/reflect_constructor_decl.h +++ b/source/reflect/include/reflect/reflect_constructor_decl.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_context.h b/source/reflect/include/reflect/reflect_context.h index 93b0782467..00c3fa0159 100644 --- a/source/reflect/include/reflect/reflect_context.h +++ b/source/reflect/include/reflect/reflect_context.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_exception.h b/source/reflect/include/reflect/reflect_exception.h index 89dedc55ff..476bb417bc 100644 --- a/source/reflect/include/reflect/reflect_exception.h +++ b/source/reflect/include/reflect/reflect_exception.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/include/reflect/reflect_function.h b/source/reflect/include/reflect/reflect_function.h index ccfdfbda08..c085541a88 100644 --- a/source/reflect/include/reflect/reflect_function.h +++ b/source/reflect/include/reflect/reflect_function.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_future.h b/source/reflect/include/reflect/reflect_future.h index 9c93fb0463..891c1c8c2e 100644 --- a/source/reflect/include/reflect/reflect_future.h +++ b/source/reflect/include/reflect/reflect_future.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_memory_tracker.h b/source/reflect/include/reflect/reflect_memory_tracker.h index 7aefbc2249..19ce783423 100644 --- a/source/reflect/include/reflect/reflect_memory_tracker.h +++ b/source/reflect/include/reflect/reflect_memory_tracker.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_method.h b/source/reflect/include/reflect/reflect_method.h index 18be52a15a..cbcb688fb2 100644 --- a/source/reflect/include/reflect/reflect_method.h +++ b/source/reflect/include/reflect/reflect_method.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_method_decl.h b/source/reflect/include/reflect/reflect_method_decl.h index a20a0f2ee4..48cc778ce8 100644 --- a/source/reflect/include/reflect/reflect_method_decl.h +++ b/source/reflect/include/reflect/reflect_method_decl.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_object.h b/source/reflect/include/reflect/reflect_object.h index 84ab9cc793..6536d89ebc 100644 --- a/source/reflect/include/reflect/reflect_object.h +++ b/source/reflect/include/reflect/reflect_object.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_scope.h b/source/reflect/include/reflect/reflect_scope.h index 8b5fe5e9d1..98ea815de7 100644 --- a/source/reflect/include/reflect/reflect_scope.h +++ b/source/reflect/include/reflect/reflect_scope.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_signature.h b/source/reflect/include/reflect/reflect_signature.h index e5e424460d..7982e9940d 100644 --- a/source/reflect/include/reflect/reflect_signature.h +++ b/source/reflect/include/reflect/reflect_signature.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_throwable.h b/source/reflect/include/reflect/reflect_throwable.h index fdc12b4fe7..fe6a40e312 100644 --- a/source/reflect/include/reflect/reflect_throwable.h +++ b/source/reflect/include/reflect/reflect_throwable.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_type.h b/source/reflect/include/reflect/reflect_type.h index e7048a2206..80bbc8b7a5 100644 --- a/source/reflect/include/reflect/reflect_type.h +++ b/source/reflect/include/reflect/reflect_type.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_type_id.h b/source/reflect/include/reflect/reflect_type_id.h index 45930c1b62..0028b33577 100644 --- a/source/reflect/include/reflect/reflect_type_id.h +++ b/source/reflect/include/reflect/reflect_type_id.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value.h b/source/reflect/include/reflect/reflect_value.h index 8b68387bb9..249770027d 100644 --- a/source/reflect/include/reflect/reflect_value.h +++ b/source/reflect/include/reflect/reflect_value.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value_type.h b/source/reflect/include/reflect/reflect_value_type.h index fdb7856b7a..ce4cf58a21 100644 --- a/source/reflect/include/reflect/reflect_value_type.h +++ b/source/reflect/include/reflect/reflect_value_type.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value_type_cast.h b/source/reflect/include/reflect/reflect_value_type_cast.h index 734b1d749d..22b7420b29 100644 --- a/source/reflect/include/reflect/reflect_value_type_cast.h +++ b/source/reflect/include/reflect/reflect_value_type_cast.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value_type_demotion.h b/source/reflect/include/reflect/reflect_value_type_demotion.h index f2aad7af23..a3060f2893 100644 --- a/source/reflect/include/reflect/reflect_value_type_demotion.h +++ b/source/reflect/include/reflect/reflect_value_type_demotion.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value_type_id_size.h b/source/reflect/include/reflect/reflect_value_type_id_size.h index 88c5a14375..294897d897 100644 --- a/source/reflect/include/reflect/reflect_value_type_id_size.h +++ b/source/reflect/include/reflect/reflect_value_type_id_size.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/include/reflect/reflect_value_type_promotion.h b/source/reflect/include/reflect/reflect_value_type_promotion.h index 21ba8da10e..c8b59d3072 100644 --- a/source/reflect/include/reflect/reflect_value_type_promotion.h +++ b/source/reflect/include/reflect/reflect_value_type_promotion.h @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect.c b/source/reflect/source/reflect.c index c8c283d11b..724628a0d9 100644 --- a/source/reflect/source/reflect.c +++ b/source/reflect/source/reflect.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -26,7 +26,7 @@ const char *reflect_print_info(void) { static const char reflect_info[] = "Reflect Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef REFLECT_STATIC_DEFINE "Compiled as static library type" diff --git a/source/reflect/source/reflect_attribute.c b/source/reflect/source/reflect_attribute.c index 7f4421ff11..420ff150e3 100644 --- a/source/reflect/source/reflect_attribute.c +++ b/source/reflect/source/reflect_attribute.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_class.c b/source/reflect/source/reflect_class.c index 650318b76c..8830cf55bf 100644 --- a/source/reflect/source/reflect_class.c +++ b/source/reflect/source/reflect_class.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -42,7 +42,7 @@ struct class_type enum accessor_type_id accessor; class_impl impl; class_interface interface; - struct threading_atomic_ref_count_type ref; + threading_atomic_ref_count_type ref; vector constructors; map methods; map static_methods; @@ -50,29 +50,17 @@ struct class_type set static_attributes; }; -struct class_metadata_iterator_args_type -{ - value v; - size_t count; -}; - -typedef struct class_metadata_iterator_args_type *class_metadata_iterator_args; - reflect_memory_tracker(class_stats); static value class_metadata_name(klass cls); static value class_metadata_constructors(klass cls); -static int class_metadata_methods_impl_cb_iterate(map m, map_key key, map_value val, map_cb_iterate_args args); static value class_metadata_methods_impl(const char name[], size_t size, map methods); static value class_metadata_methods(klass cls); static value class_metadata_static_methods(klass cls); -static int class_metadata_attributes_impl_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); static value class_metadata_attributes_impl(const char name[], size_t size, set attributes); static value class_metadata_attributes(klass cls); static value class_metadata_static_attributes(klass cls); static method class_get_method_type_safe(vector v, type_id ret, type_id args[], size_t size); -static int class_attributes_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); -static int class_methods_destroy_cb_iterate(map m, map_key key, map_value val, map_cb_iterate_args args); static void class_constructors_destroy(klass cls); klass class_create(const char *name, enum accessor_type_id accessor, class_impl impl, class_impl_interface_singleton singleton) @@ -123,6 +111,7 @@ klass class_create(const char *name, enum accessor_type_id accessor, class_impl log_write("metacall", LOG_LEVEL_ERROR, "Invalid class (%s) create callback <%p>", cls->name, cls->interface->create); free(cls->name); + threading_atomic_ref_count_destroy(&cls->ref); vector_destroy(cls->constructors); map_destroy(cls->methods); map_destroy(cls->static_methods); @@ -261,23 +250,12 @@ value class_metadata_constructors(klass cls) return v; } -int class_metadata_methods_impl_cb_iterate(map m, map_key key, map_value val, map_cb_iterate_args args) -{ - class_metadata_iterator_args iterator = (class_metadata_iterator_args)args; - value *v_array = value_to_array(iterator->v); - - (void)m; - (void)key; - - v_array[iterator->count++] = method_metadata((method)val); - - return 0; -} - value class_metadata_methods_impl(const char name[], size_t size, map methods) { value v = value_create_array(NULL, 2); value *v_array; + struct map_iterator_type it; + size_t count; if (v == NULL) { @@ -299,12 +277,12 @@ value class_metadata_methods_impl(const char name[], size_t size, map methods) goto error_value; } - struct class_metadata_iterator_args_type iterator; - - iterator.v = v_array[1]; - iterator.count = 0; + for (map_iterator_begin(&it, methods), count = 0; map_iterator_end(&it) != 0; map_iterator_next(&it)) + { + value *method_array = value_to_array(v_array[1]); - map_iterate(methods, &class_metadata_methods_impl_cb_iterate, &iterator); + method_array[count++] = method_metadata((method)map_iterator_value(&it)); + } return v; error_value: @@ -324,23 +302,12 @@ value class_metadata_static_methods(klass cls) return class_metadata_methods_impl(name, sizeof(name), cls->static_methods); } -int class_metadata_attributes_impl_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - class_metadata_iterator_args iterator = (class_metadata_iterator_args)args; - value *v_array = value_to_array(iterator->v); - - (void)s; - (void)key; - - v_array[iterator->count++] = attribute_metadata((attribute)val); - - return 0; -} - value class_metadata_attributes_impl(const char name[], size_t size, set attributes) { value v = value_create_array(NULL, 2); value *v_array; + struct set_iterator_type it; + size_t count; if (v == NULL) { @@ -362,12 +329,12 @@ value class_metadata_attributes_impl(const char name[], size_t size, set attribu goto error_value; } - struct class_metadata_iterator_args_type iterator; - - iterator.v = v_array[1]; - iterator.count = 0; + for (set_iterator_begin(&it, attributes), count = 0; set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + value *attribute_array = value_to_array(v_array[1]); - set_iterate(attributes, &class_metadata_attributes_impl_cb_iterate, &iterator); + attribute_array[count++] = attribute_metadata(set_iterator_value(&it)); + } return v; error_value: @@ -790,33 +757,6 @@ value class_static_await(klass cls, method m, class_args args, size_t size, clas return NULL; } -int class_attributes_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - (void)args; - - if (val != NULL) - { - attribute attr = val; - - attribute_destroy(attr); - } - - return 0; -} - -int class_methods_destroy_cb_iterate(map m, map_key key, map_value val, map_cb_iterate_args args) -{ - (void)m; - (void)key; - (void)args; - - method_destroy((method)val); - - return 0; -} - void class_constructors_destroy(klass cls) { size_t iterator, size = vector_size(cls->constructors); @@ -860,11 +800,35 @@ void class_destroy(klass cls) class_constructors_destroy(cls); - set_iterate(cls->attributes, &class_attributes_destroy_cb_iterate, NULL); - set_iterate(cls->static_attributes, &class_attributes_destroy_cb_iterate, NULL); + /* Destroy attributes */ + { + struct set_iterator_type it; + + for (set_iterator_begin(&it, cls->attributes); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + attribute_destroy(set_iterator_value(&it)); + } + + for (set_iterator_begin(&it, cls->static_attributes); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + attribute_destroy(set_iterator_value(&it)); + } + } - map_iterate(cls->methods, &class_methods_destroy_cb_iterate, NULL); - map_iterate(cls->static_methods, &class_methods_destroy_cb_iterate, NULL); + /* Destroy methods */ + { + struct map_iterator_type it; + + for (map_iterator_begin(&it, cls->methods); map_iterator_end(&it) != 0; map_iterator_next(&it)) + { + method_destroy(map_iterator_value(&it)); + } + + for (map_iterator_begin(&it, cls->static_methods); map_iterator_end(&it) != 0; map_iterator_next(&it)) + { + method_destroy(map_iterator_value(&it)); + } + } if (cls->interface != NULL && cls->interface->destroy != NULL) { diff --git a/source/reflect/source/reflect_class_visibility.c b/source/reflect/source/reflect_class_visibility.c index e32a3d504e..93cd90c865 100644 --- a/source/reflect/source/reflect_class_visibility.c +++ b/source/reflect/source/reflect_class_visibility.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_constructor.c b/source/reflect/source/reflect_constructor.c index bb264e1a69..c12a9c25f9 100644 --- a/source/reflect/source/reflect_constructor.c +++ b/source/reflect/source/reflect_constructor.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_context.c b/source/reflect/source/reflect_context.c index bf203b8b42..e0e7ee3262 100644 --- a/source/reflect/source/reflect_context.c +++ b/source/reflect/source/reflect_context.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_exception.c b/source/reflect/source/reflect_exception.c index 1225031218..7a85d46b0e 100644 --- a/source/reflect/source/reflect_exception.c +++ b/source/reflect/source/reflect_exception.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -37,7 +37,7 @@ struct exception_type int64_t code; /* Numeric code of error */ char *stacktrace; /* Stack trace of the error */ uint64_t id; /* Thread id where the error was raised */ - struct threading_atomic_ref_count_type ref; + threading_atomic_ref_count_type ref; /* TODO: value attributes; // This should implement a map for representing the extra attributes of an exception */ }; @@ -138,15 +138,88 @@ exception exception_create_const(const char *message, const char *label, int64_t return ex; stacktrace_bad_alloc: - free(ex->label); + if (ex->label != NULL) + { + free(ex->label); + } label_bad_alloc: - free(ex->message); + if (ex->message != NULL) + { + free(ex->message); + } message_bad_alloc: free(ex); exception_bad_alloc: 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) diff --git a/source/reflect/source/reflect_function.c b/source/reflect/source/reflect_function.c index 692ca28d5a..b9a03512f8 100644 --- a/source/reflect/source/reflect_function.c +++ b/source/reflect/source/reflect_function.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -36,7 +36,7 @@ struct function_type signature s; function_impl impl; function_interface interface; - struct threading_atomic_ref_count_type ref; + threading_atomic_ref_count_type ref; enum async_id async; void *data; }; @@ -66,9 +66,7 @@ function function_create(const char *name, size_t args_count, function_impl impl { log_write("metacall", LOG_LEVEL_ERROR, "Invalid function name allocation <%s>", name); - free(func); - - return NULL; + goto name_error; } memcpy(func->name, name, func_name_size); @@ -88,7 +86,7 @@ function function_create(const char *name, size_t args_count, function_impl impl { log_write("metacall", LOG_LEVEL_ERROR, "Invalid function signature allocation"); - goto function_create_error; + goto signature_error; } threading_atomic_ref_count_initialize(&func->ref); @@ -101,7 +99,7 @@ function function_create(const char *name, size_t args_count, function_impl impl { log_write("metacall", LOG_LEVEL_ERROR, "Invalid function (%s) create callback <%p>", func->name, func->interface->create); - goto function_create_error; + goto interface_create_error; } } @@ -109,8 +107,14 @@ function function_create(const char *name, size_t args_count, function_impl impl return func; -function_create_error: - free(func->name); +interface_create_error: + signature_destroy(func->s); +signature_error: + if (func->name != NULL) + { + free(func->name); + } +name_error: free(func); return NULL; diff --git a/source/reflect/source/reflect_future.c b/source/reflect/source/reflect_future.c index e2b7ebb926..86ab560ab7 100644 --- a/source/reflect/source/reflect_future.c +++ b/source/reflect/source/reflect_future.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_memory_tracker.c b/source/reflect/source/reflect_memory_tracker.c index ba13440573..e810571fe1 100644 --- a/source/reflect/source/reflect_memory_tracker.c +++ b/source/reflect/source/reflect_memory_tracker.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_method.c b/source/reflect/source/reflect_method.c index 7f47a2b41e..e4b4bc6880 100644 --- a/source/reflect/source/reflect_method.c +++ b/source/reflect/source/reflect_method.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_object.c b/source/reflect/source/reflect_object.c index 6d64cbcd97..a568b24d70 100644 --- a/source/reflect/source/reflect_object.c +++ b/source/reflect/source/reflect_object.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -40,7 +40,7 @@ struct object_type enum accessor_type_id accessor; object_impl impl; object_interface interface; - struct threading_atomic_ref_count_type ref; + threading_atomic_ref_count_type ref; klass cls; }; @@ -67,9 +67,7 @@ object object_create(const char *name, enum accessor_type_id accessor, object_im { log_write("metacall", LOG_LEVEL_ERROR, "Invalid object name allocation <%s>", name); - free(obj); - - return NULL; + goto name_error; } memcpy(obj->name, name, obj_name_size); @@ -79,12 +77,11 @@ object object_create(const char *name, enum accessor_type_id accessor, object_im obj->name = NULL; } - obj->impl = impl; - obj->accessor = accessor; threading_atomic_ref_count_initialize(&obj->ref); + obj->impl = impl; + obj->accessor = accessor; obj->interface = singleton ? singleton() : NULL; - obj->cls = cls; if (obj->interface != NULL && obj->interface->create != NULL) @@ -93,16 +90,23 @@ object object_create(const char *name, enum accessor_type_id accessor, object_im { log_write("metacall", LOG_LEVEL_ERROR, "Invalid object (%s) create callback <%p>", obj->name, obj->interface->create); - free(obj->name); - free(obj); - - return NULL; + goto interface_create_error; } } reflect_memory_tracker_allocation(object_stats); return obj; + +interface_create_error: + if (obj->name != NULL) + { + free(obj->name); + } +name_error: + free(obj); + + return NULL; } int object_increment_reference(object obj) diff --git a/source/reflect/source/reflect_scope.c b/source/reflect/source/reflect_scope.c index f7d82f35c5..1da2285bfc 100644 --- a/source/reflect/source/reflect_scope.c +++ b/source/reflect/source/reflect_scope.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -30,14 +30,6 @@ #include <stdlib.h> #include <string.h> -struct scope_metadata_array_cb_iterator_type; - -struct scope_export_cb_iterator_type; - -typedef struct scope_metadata_array_cb_iterator_type *scope_metadata_array_cb_iterator; - -typedef struct scope_export_cb_iterator_type *scope_export_cb_iterator; - struct scope_type { char *name; /**< Scope name */ @@ -45,32 +37,11 @@ struct scope_type vector call_stack; /**< Scope call stack */ }; -struct scope_metadata_array_cb_iterator_type -{ - value *functions; - value *classes; - value *objects; - - size_t functions_size; - size_t classes_size; - size_t objects_size; -}; - -struct scope_export_cb_iterator_type -{ - size_t iterator; - value *values; -}; - -static int scope_metadata_array_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - -static int scope_export_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); - static int scope_metadata_array(scope sp, value v_array[3]); static value scope_metadata_name(scope sp); -static int scope_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args); +static value scope_export_value(const char *key, value val); scope scope_create(const char *name) { @@ -193,106 +164,94 @@ int scope_define(scope sp, const char *key, value val) return 1; } -int scope_metadata_array_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) +int scope_metadata_array(scope sp, value v_array[3]) { - scope_metadata_array_cb_iterator metadata_iterator = (scope_metadata_array_cb_iterator)args; + size_t functions_size = 0, classes_size = 0, objects_size = 0; + value functions_value, classes_value, objects_value; + value *functions, *classes, *objects; + struct set_iterator_type it; - (void)s; - (void)key; - - int type_id = value_type_id(val); - - if (type_id == TYPE_FUNCTION) + for (set_iterator_begin(&it, sp->objects); set_iterator_end(&it) != 0; set_iterator_next(&it)) { - metadata_iterator->functions[metadata_iterator->functions_size++] = function_metadata(value_to_function(val)); - } - else if (type_id == TYPE_CLASS) - { - metadata_iterator->classes[metadata_iterator->classes_size++] = class_metadata(value_to_class(val)); - } - else if (type_id == TYPE_OBJECT) - { - metadata_iterator->objects[metadata_iterator->objects_size++] = object_metadata(value_to_object(val)); - } - - return 0; -} - -int scope_metadata_array_cb_iterate_counter(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - scope_metadata_array_cb_iterator metadata_iterator = (scope_metadata_array_cb_iterator)args; - - (void)s; - (void)key; - - type_id id = value_type_id(val); + type_id id = value_type_id(set_iterator_value(&it)); - if (id == TYPE_FUNCTION) - { - metadata_iterator->functions_size++; - } - else if (id == TYPE_CLASS) - { - metadata_iterator->classes_size++; - } - else if (id == TYPE_OBJECT) - { - metadata_iterator->objects_size++; + if (id == TYPE_FUNCTION) + { + functions_size++; + } + else if (id == TYPE_CLASS) + { + classes_size++; + } + else if (id == TYPE_OBJECT) + { + objects_size++; + } } - return 0; -} - -int scope_metadata_array(scope sp, value v_array[3]) -{ - struct scope_metadata_array_cb_iterator_type metadata_iterator = { - NULL, NULL, NULL, 0, 0, 0 - }; + functions_value = value_create_array(NULL, functions_size); - set_iterate(sp->objects, &scope_metadata_array_cb_iterate_counter, (set_cb_iterate_args)&metadata_iterator); - - value functions_val = value_create_array(NULL, metadata_iterator.functions_size); - - if (functions_val == NULL) + if (functions_value == NULL) { - return 1; + goto functions_error; } - metadata_iterator.functions = value_to_array(functions_val); + functions = value_to_array(functions_value); - value classes_val = value_create_array(NULL, metadata_iterator.classes_size); + classes_value = value_create_array(NULL, classes_size); - if (classes_val == NULL) + if (classes_value == NULL) { - value_destroy(functions_val); - return 1; + goto classes_error; } - metadata_iterator.classes = value_to_array(classes_val); + classes = value_to_array(classes_value); - value objects_val = value_create_array(NULL, metadata_iterator.objects_size); + objects_value = value_create_array(NULL, objects_size); - if (objects_val == NULL) + if (objects_value == NULL) { - value_destroy(functions_val); - value_destroy(classes_val); - return 1; + goto objects_error; } - metadata_iterator.objects = value_to_array(objects_val); + objects = value_to_array(objects_value); /* Reuse counters to fill the arrays */ - metadata_iterator.classes_size = 0; - metadata_iterator.functions_size = 0; - metadata_iterator.objects_size = 0; + classes_size = 0; + functions_size = 0; + objects_size = 0; + + for (set_iterator_begin(&it, sp->objects); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + value v = set_iterator_value(&it); + type_id id = value_type_id(v); - set_iterate(sp->objects, &scope_metadata_array_cb_iterate, (set_cb_iterate_args)&metadata_iterator); + if (id == TYPE_FUNCTION) + { + functions[functions_size++] = function_metadata(value_to_function(v)); + } + else if (id == TYPE_CLASS) + { + classes[classes_size++] = class_metadata(value_to_class(v)); + } + else if (id == TYPE_OBJECT) + { + objects[objects_size++] = object_metadata(value_to_object(v)); + } + } - v_array[0] = functions_val; - v_array[1] = classes_val; - v_array[2] = objects_val; + v_array[0] = functions_value; + v_array[1] = classes_value; + v_array[2] = objects_value; return 0; + +objects_error: + value_destroy(classes_value); +classes_error: + value_destroy(functions_value); +functions_error: + return 1; } value scope_metadata_name(scope sp) @@ -379,62 +338,60 @@ value scope_metadata(scope sp) return v; } -int scope_export_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) +value scope_export_value(const char *key, value val) { - scope_export_cb_iterator export_iterator = (scope_export_cb_iterator)args; - - const char *key_str = (const char *)key; - value *v_array, v = value_create_array(NULL, 2); - (void)s; - if (v == NULL) { - return 0; + goto array_create_error; } v_array = value_to_array(v); - v_array[0] = value_create_string(key_str, strlen(key_str)); + v_array[0] = value_create_string(key, strlen(key)); if (v_array[0] == NULL) { - value_type_destroy(v); - - return 0; + goto string_create_error; } v_array[1] = value_type_copy(val); if (v_array[1] == NULL) { - value_type_destroy(v); - - return 0; + goto value_copy_error; } - export_iterator->values[export_iterator->iterator] = v; - ++export_iterator->iterator; + return v; - return 0; +value_copy_error: + value_type_destroy(v_array[0]); +string_create_error: + value_type_destroy(v); +array_create_error: + return NULL; } value scope_export(scope sp) { - struct scope_export_cb_iterator_type export_iterator; - - value export = value_create_map(NULL, scope_size(sp)); + value *values, export = value_create_map(NULL, scope_size(sp)); + size_t values_it; + struct set_iterator_type it; if (export == NULL) { return NULL; } - export_iterator.iterator = 0; - export_iterator.values = value_to_map(export); + values = value_to_map(export); - set_iterate(sp->objects, &scope_export_cb_iterate, (set_cb_iterate_args)&export_iterator); + for (set_iterator_begin(&it, sp->objects), values_it = 0; set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + value v = scope_export_value(set_iterator_key(&it), set_iterator_value(&it)); + + values[values_it++] = v; + } return export; } @@ -592,27 +549,16 @@ int scope_stack_pop(scope sp) return 1; } -int scope_destroy_cb_iterate(set s, set_key key, set_value val, set_cb_iterate_args args) -{ - (void)s; - (void)key; - (void)args; - - if (val != NULL) - { - value_type_destroy(val); - - return 0; - } - - return 1; -} - void scope_destroy(scope sp) { if (sp != NULL) { - set_iterate(sp->objects, &scope_destroy_cb_iterate, NULL); + struct set_iterator_type it; + + for (set_iterator_begin(&it, sp->objects); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + value_type_destroy(set_iterator_value(&it)); + } set_destroy(sp->objects); diff --git a/source/reflect/source/reflect_signature.c b/source/reflect/source/reflect_signature.c index 94536d8d14..04c7ba3d61 100644 --- a/source/reflect/source/reflect_signature.c +++ b/source/reflect/source/reflect_signature.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_throwable.c b/source/reflect/source/reflect_throwable.c index 56929e0edb..d64c767407 100644 --- a/source/reflect/source/reflect_throwable.c +++ b/source/reflect/source/reflect_throwable.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_type.c b/source/reflect/source/reflect_type.c index ea46ed69e2..ed7786b792 100644 --- a/source/reflect/source/reflect_type.c +++ b/source/reflect/source/reflect_type.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_type_id.c b/source/reflect/source/reflect_type_id.c index 1b5f99d207..b168dd6fa9 100644 --- a/source/reflect/source/reflect_type_id.c +++ b/source/reflect/source/reflect_type_id.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_value.c b/source/reflect/source/reflect_value.c index 8fa3537526..6b8b19b6ba 100644 --- a/source/reflect/source/reflect_value.c +++ b/source/reflect/source/reflect_value.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_value_type.c b/source/reflect/source/reflect_value_type.c index dcae4ce6f0..cc56921610 100644 --- a/source/reflect/source/reflect_value_type.c +++ b/source/reflect/source/reflect_value_type.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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; diff --git a/source/reflect/source/reflect_value_type_cast.c b/source/reflect/source/reflect_value_type_cast.c index 126ddcd6e4..e7b6670265 100644 --- a/source/reflect/source/reflect_value_type_cast.c +++ b/source/reflect/source/reflect_value_type_cast.c @@ -1,6 +1,6 @@ /* * Reflect Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A library for provide reflection and metadata representation. * @@ -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/reflect/source/reflect_value_type_demotion.c b/source/reflect/source/reflect_value_type_demotion.c index 01f25a0388..580c813854 100644 --- a/source/reflect/source/reflect_value_type_demotion.c +++ b/source/reflect/source/reflect_value_type_demotion.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_value_type_id_size.c b/source/reflect/source/reflect_value_type_id_size.c index 2ad67dc0b3..bf18225cd2 100644 --- a/source/reflect/source/reflect_value_type_id_size.c +++ b/source/reflect/source/reflect_value_type_id_size.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/reflect/source/reflect_value_type_promotion.c b/source/reflect/source/reflect_value_type_promotion.c index f7d255028d..2eb66183fe 100644 --- a/source/reflect/source/reflect_value_type_promotion.c +++ b/source/reflect/source/reflect_value_type_promotion.c @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/scripts/c/cmake/CProject.cmake b/source/scripts/c/cmake/CProject.cmake index 473c00be61..a68a08c41a 100644 --- a/source/scripts/c/cmake/CProject.cmake +++ b/source/scripts/c/cmake/CProject.cmake @@ -2,7 +2,7 @@ # C project generator by Parra Studios # Generates a C project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/c/cmake/CProject.cmake.in b/source/scripts/c/cmake/CProject.cmake.in index 7ebe352086..0a81fe64be 100644 --- a/source/scripts/c/cmake/CProject.cmake.in +++ b/source/scripts/c/cmake/CProject.cmake.in @@ -2,7 +2,7 @@ # C project generator by Parra Studios # Generates a C project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/c/compiled/source/compiled.c b/source/scripts/c/compiled/source/compiled.c index b7468cde78..8493e28d98 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,136 @@ 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); +} + +/* 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) +{ + printf("l %p\n", l); + printf("value %d\n", *l); + fflush(stdout); + assert(*l == 324444L); + *l = 111L; +} + +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; +} + +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); + *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 8dcb43dedb..3bc2b63289 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) @@ -12,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; @@ -23,6 +27,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; } @@ -33,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/scripts/c/loadtest/source/loadtest.h b/source/scripts/c/loadtest/source/loadtest.h index 3e4f072748..4a93356958 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 { diff --git a/source/scripts/cobol/cmake/CobolProject.cmake b/source/scripts/cobol/cmake/CobolProject.cmake index 0e860b289b..509053219a 100644 --- a/source/scripts/cobol/cmake/CobolProject.cmake +++ b/source/scripts/cobol/cmake/CobolProject.cmake @@ -2,7 +2,7 @@ # Cobol project generator by Parra Studios # Generates a Cobol project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/cobol/cmake/CobolProject.cmake.in b/source/scripts/cobol/cmake/CobolProject.cmake.in index 5392b9d530..a982974ee9 100644 --- a/source/scripts/cobol/cmake/CobolProject.cmake.in +++ b/source/scripts/cobol/cmake/CobolProject.cmake.in @@ -2,7 +2,7 @@ # Cobol project generator by Parra Studios # Generates a Cobol project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/csharp/cmake/CSharpProject.cmake b/source/scripts/csharp/cmake/CSharpProject.cmake index add3f9a838..9d8d9c708b 100644 --- a/source/scripts/csharp/cmake/CSharpProject.cmake +++ b/source/scripts/csharp/cmake/CSharpProject.cmake @@ -2,7 +2,7 @@ # CSharp project generator by Parra Studios # Generates a csharp project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/csharp/cmake/CSharpProject.cmake.in b/source/scripts/csharp/cmake/CSharpProject.cmake.in index d405caf5d7..63cd335d8e 100644 --- a/source/scripts/csharp/cmake/CSharpProject.cmake.in +++ b/source/scripts/csharp/cmake/CSharpProject.cmake.in @@ -2,7 +2,7 @@ # CSharp project generator by Parra Studios # Generates a csharp project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/csharp/cmake/CSharpProject.json.in b/source/scripts/csharp/cmake/CSharpProject.json.in index 0a0ae67d41..2e04025712 100644 --- a/source/scripts/csharp/cmake/CSharpProject.json.in +++ b/source/scripts/csharp/cmake/CSharpProject.json.in @@ -3,7 +3,7 @@ # CSharp project generator by Parra Studios # Generates a csharp project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/extension/sum/CMakeLists.txt b/source/scripts/extension/sum/CMakeLists.txt index 223a700660..735866c143 100644 --- a/source/scripts/extension/sum/CMakeLists.txt +++ b/source/scripts/extension/sum/CMakeLists.txt @@ -152,7 +152,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/scripts/extension/sum/include/sum_extension/sum_extension.h b/source/scripts/extension/sum/include/sum_extension/sum_extension.h index 4dd93bc046..f3f966fc70 100644 --- a/source/scripts/extension/sum/include/sum_extension/sum_extension.h +++ b/source/scripts/extension/sum/include/sum_extension/sum_extension.h @@ -2,7 +2,7 @@ * Extension Library by Parra Studios * An extension for sum numbers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -23,16 +23,12 @@ #include <sum_extension/sum_extension_api.h> -#include <dynlink/dynlink.h> - #ifdef __cplusplus extern "C" { #endif SUM_EXTENSION_API int sum_extension(void *loader, void *handle); -DYNLINK_SYMBOL_EXPORT(sum_extension); - #ifdef __cplusplus } #endif diff --git a/source/scripts/extension/sum/source/sum_extension.cpp b/source/scripts/extension/sum/source/sum_extension.cpp index e4856306d2..1c707b93d1 100644 --- a/source/scripts/extension/sum/source/sum_extension.cpp +++ b/source/scripts/extension/sum/source/sum_extension.cpp @@ -2,7 +2,7 @@ * Extension Library by Parra Studios * An extension for sum numbers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/scripts/file/cmake/FileProject.cmake b/source/scripts/file/cmake/FileProject.cmake index 3ee6aedaab..e8a3e13564 100644 --- a/source/scripts/file/cmake/FileProject.cmake +++ b/source/scripts/file/cmake/FileProject.cmake @@ -2,7 +2,7 @@ # File project generator by Parra Studios # Generates a file project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/file/cmake/FileProject.cmake.in b/source/scripts/file/cmake/FileProject.cmake.in index 7a41294423..ff059ec858 100644 --- a/source/scripts/file/cmake/FileProject.cmake.in +++ b/source/scripts/file/cmake/FileProject.cmake.in @@ -2,7 +2,7 @@ # File project generator by Parra Studios # Generates a file project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/java/cmake/JavaJarProject.cmake.in b/source/scripts/java/cmake/JavaJarProject.cmake.in index 03bad21cd2..d6c0d87477 100644 --- a/source/scripts/java/cmake/JavaJarProject.cmake.in +++ b/source/scripts/java/cmake/JavaJarProject.cmake.in @@ -2,7 +2,7 @@ # Java project generator by Parra Studios # Generates a java project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/java/cmake/JavaProject.cmake b/source/scripts/java/cmake/JavaProject.cmake index 46e4b0c30c..51874c9093 100644 --- a/source/scripts/java/cmake/JavaProject.cmake +++ b/source/scripts/java/cmake/JavaProject.cmake @@ -2,7 +2,7 @@ # Java project generator by Parra Studios # Generates a java project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/java/cmake/JavaProject.cmake.in b/source/scripts/java/cmake/JavaProject.cmake.in index 5d2472b854..0b74b6bdfa 100644 --- a/source/scripts/java/cmake/JavaProject.cmake.in +++ b/source/scripts/java/cmake/JavaProject.cmake.in @@ -2,7 +2,7 @@ # Java project generator by Parra Studios # Generates a java project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/javascript/cmake/JavaScriptProject.cmake b/source/scripts/javascript/cmake/JavaScriptProject.cmake index f7dd907d39..d5762770bc 100644 --- a/source/scripts/javascript/cmake/JavaScriptProject.cmake +++ b/source/scripts/javascript/cmake/JavaScriptProject.cmake @@ -2,7 +2,7 @@ # JavaScript project generator by Parra Studios # Generates a javascript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/javascript/cmake/JavaScriptProject.cmake.in b/source/scripts/javascript/cmake/JavaScriptProject.cmake.in index d0da4daae8..91375592f1 100644 --- a/source/scripts/javascript/cmake/JavaScriptProject.cmake.in +++ b/source/scripts/javascript/cmake/JavaScriptProject.cmake.in @@ -2,7 +2,7 @@ # JavaScript project generator by Parra Studios # Generates a javascript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/javascript/cmake/JavaScriptProject.json.in b/source/scripts/javascript/cmake/JavaScriptProject.json.in index ea997c6ec5..82ff04239f 100644 --- a/source/scripts/javascript/cmake/JavaScriptProject.json.in +++ b/source/scripts/javascript/cmake/JavaScriptProject.json.in @@ -3,7 +3,7 @@ # JavaScript project generator by Parra Studios # Generates a javascript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/julia/cmake/JuliaProject.cmake b/source/scripts/julia/cmake/JuliaProject.cmake index 770e8cfc37..3e5f2af41b 100644 --- a/source/scripts/julia/cmake/JuliaProject.cmake +++ b/source/scripts/julia/cmake/JuliaProject.cmake @@ -2,7 +2,7 @@ # Julia project generator by Parra Studios # Generates a Julia project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/julia/cmake/JuliaProject.cmake.in b/source/scripts/julia/cmake/JuliaProject.cmake.in index 95aa5c3397..b4f049b2e3 100644 --- a/source/scripts/julia/cmake/JuliaProject.cmake.in +++ b/source/scripts/julia/cmake/JuliaProject.cmake.in @@ -2,7 +2,7 @@ # Julia project generator by Parra Studios # Generates a Julia project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/llvm/cmake/LLVMProject.cmake b/source/scripts/llvm/cmake/LLVMProject.cmake index 7f2a70d337..173360dfc1 100644 --- a/source/scripts/llvm/cmake/LLVMProject.cmake +++ b/source/scripts/llvm/cmake/LLVMProject.cmake @@ -2,7 +2,7 @@ # LLVM project generator by Parra Studios # Generates a LLVM project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/llvm/cmake/LLVMProject.cmake.in b/source/scripts/llvm/cmake/LLVMProject.cmake.in index 9a6ad77707..bc379d3b08 100644 --- a/source/scripts/llvm/cmake/LLVMProject.cmake.in +++ b/source/scripts/llvm/cmake/LLVMProject.cmake.in @@ -2,7 +2,7 @@ # LLVM project generator by Parra Studios # Generates a LLVM project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/lua/cmake/LuaProject.cmake b/source/scripts/lua/cmake/LuaProject.cmake index da4ee1247d..46c8b81035 100644 --- a/source/scripts/lua/cmake/LuaProject.cmake +++ b/source/scripts/lua/cmake/LuaProject.cmake @@ -2,7 +2,7 @@ # Lua project generator by Parra Studios # Generates a lua project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/lua/cmake/LuaProject.cmake.in b/source/scripts/lua/cmake/LuaProject.cmake.in index 8bc5b2eec2..bc094e00f2 100644 --- a/source/scripts/lua/cmake/LuaProject.cmake.in +++ b/source/scripts/lua/cmake/LuaProject.cmake.in @@ -2,7 +2,7 @@ # Lua project generator by Parra Studios # Generates a Lua project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/node/cmake/NodeJSProject.cmake b/source/scripts/node/cmake/NodeJSProject.cmake index 60a093c88a..32dc8e45f4 100644 --- a/source/scripts/node/cmake/NodeJSProject.cmake +++ b/source/scripts/node/cmake/NodeJSProject.cmake @@ -2,7 +2,7 @@ # NodeJS project generator by Parra Studios # Generates a nodejs project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/node/cmake/NodeJSProject.cmake.in b/source/scripts/node/cmake/NodeJSProject.cmake.in index f9c3d86a6b..da69b7730a 100644 --- a/source/scripts/node/cmake/NodeJSProject.cmake.in +++ b/source/scripts/node/cmake/NodeJSProject.cmake.in @@ -2,7 +2,7 @@ # NodeJS project generator by Parra Studios # Generates a NodeJS project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/node/cmake/NodeJSProject.json.in b/source/scripts/node/cmake/NodeJSProject.json.in index 980b150d32..80006864dd 100644 --- a/source/scripts/node/cmake/NodeJSProject.json.in +++ b/source/scripts/node/cmake/NodeJSProject.json.in @@ -3,7 +3,7 @@ # NodeJS project generator by Parra Studios # Generates a nodejs project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/python/cmake/PythonProject.cmake b/source/scripts/python/cmake/PythonProject.cmake index ae14b9f78d..7e38133687 100644 --- a/source/scripts/python/cmake/PythonProject.cmake +++ b/source/scripts/python/cmake/PythonProject.cmake @@ -2,7 +2,7 @@ # Python project generator by Parra Studios # Generates a python project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/python/cmake/PythonProject.cmake.in b/source/scripts/python/cmake/PythonProject.cmake.in index b423832f82..97fba6cedb 100644 --- a/source/scripts/python/cmake/PythonProject.cmake.in +++ b/source/scripts/python/cmake/PythonProject.cmake.in @@ -2,7 +2,7 @@ # Python project generator by Parra Studios # Generates a python project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/python/cmake/PythonProject.py.in b/source/scripts/python/cmake/PythonProject.py.in index cba8a94dec..521db16ceb 100644 --- a/source/scripts/python/cmake/PythonProject.py.in +++ b/source/scripts/python/cmake/PythonProject.py.in @@ -4,7 +4,7 @@ # Python project generator by Parra Studios # Generates a python project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/python/garbage/source/garbage.py b/source/scripts/python/garbage/source/garbage.py index 93c5e97c67..82dfcd1136 100644 --- a/source/scripts/python/garbage/source/garbage.py +++ b/source/scripts/python/garbage/source/garbage.py @@ -6,4 +6,4 @@ def set_debug(): gc.set_debug(gc.DEBUG_LEAK | gc.DEBUG_STATS) def garbage(): - return ''.join(gc.garbage) + return repr(gc.garbage) diff --git a/source/scripts/python/rsasample/source/rsasample.py b/source/scripts/python/rsasample/source/rsasample.py index b1aa868c77..fb9ccbfc01 100644 --- a/source/scripts/python/rsasample/source/rsasample.py +++ b/source/scripts/python/rsasample/source/rsasample.py @@ -4,7 +4,7 @@ # RSA String Encriptation Decriptation Sample by Parra Studios # Python RSA encriptation decriptation sample. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/python/rsasample/source/sample/rsa_strings.py b/source/scripts/python/rsasample/source/sample/rsa_strings.py index 80591575de..b4ccfcb36d 100644 --- a/source/scripts/python/rsasample/source/sample/rsa_strings.py +++ b/source/scripts/python/rsasample/source/sample/rsa_strings.py @@ -4,7 +4,7 @@ # RSA String Encriptation Decriptation Sample by Parra Studios # Python RSA encriptation decriptation sample. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/rpc/cmake/RPCProject.cmake b/source/scripts/rpc/cmake/RPCProject.cmake index 38f4bac0c7..a1a89df770 100644 --- a/source/scripts/rpc/cmake/RPCProject.cmake +++ b/source/scripts/rpc/cmake/RPCProject.cmake @@ -2,7 +2,7 @@ # RPC project generator by Parra Studios # Generates a rpc project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/rpc/cmake/RPCProject.cmake.in b/source/scripts/rpc/cmake/RPCProject.cmake.in index 0a5b9e215e..4eb4d931ec 100644 --- a/source/scripts/rpc/cmake/RPCProject.cmake.in +++ b/source/scripts/rpc/cmake/RPCProject.cmake.in @@ -2,7 +2,7 @@ # RPC project generator by Parra Studios # Generates a RPC project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/ruby/CMakeLists.txt b/source/scripts/ruby/CMakeLists.txt index 07ca3c8484..46dc789cd7 100644 --- a/source/scripts/ruby/CMakeLists.txt +++ b/source/scripts/ruby/CMakeLists.txt @@ -21,3 +21,4 @@ add_subdirectory(ducktype) add_subdirectory(invalid) add_subdirectory(klass) add_subdirectory(failempty) +add_subdirectory(simplest) diff --git a/source/scripts/ruby/cmake/RubyProject.cmake b/source/scripts/ruby/cmake/RubyProject.cmake index bfa73a1f4e..12f50be55d 100644 --- a/source/scripts/ruby/cmake/RubyProject.cmake +++ b/source/scripts/ruby/cmake/RubyProject.cmake @@ -2,7 +2,7 @@ # Ruby project generator by Parra Studios # Generates a ruby project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/ruby/cmake/RubyProject.cmake.in b/source/scripts/ruby/cmake/RubyProject.cmake.in index 7c81d82031..2bf28ee0ad 100644 --- a/source/scripts/ruby/cmake/RubyProject.cmake.in +++ b/source/scripts/ruby/cmake/RubyProject.cmake.in @@ -2,7 +2,7 @@ # Ruby project generator by Parra Studios # Generates a ruby project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/ruby/cmake/RubyProject.rb.in b/source/scripts/ruby/cmake/RubyProject.rb.in index 66fe0cf541..0e8ae4100f 100644 --- a/source/scripts/ruby/cmake/RubyProject.rb.in +++ b/source/scripts/ruby/cmake/RubyProject.rb.in @@ -4,7 +4,7 @@ # Ruby project generator by Parra Studios # Generates a ruby project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/ruby/klass/source/klass.rb b/source/scripts/ruby/klass/source/klass.rb index ad37a45739..86e392930a 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 - diff --git a/source/scripts/ruby/simplest/CMakeLists.txt b/source/scripts/ruby/simplest/CMakeLists.txt new file mode 100644 index 0000000000..ab31b4b0b0 --- /dev/null +++ b/source/scripts/ruby/simplest/CMakeLists.txt @@ -0,0 +1,5 @@ +# +# Configure ruby project +# + +rb_project(simplest 0.1.0) diff --git a/source/scripts/ruby/simplest/source/simplest.rb b/source/scripts/ruby/simplest/source/simplest.rb new file mode 100644 index 0000000000..5adade7138 --- /dev/null +++ b/source/scripts/ruby/simplest/source/simplest.rb @@ -0,0 +1,3 @@ +#!/usr/bin/ruby + +print("Hello from Ruby") diff --git a/source/scripts/rust/cmake/RustProject.cmake b/source/scripts/rust/cmake/RustProject.cmake index 5694e29e56..762f8dd097 100644 --- a/source/scripts/rust/cmake/RustProject.cmake +++ b/source/scripts/rust/cmake/RustProject.cmake @@ -2,7 +2,7 @@ # Rust project generator by Parra Studios # Generates a Rust project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/rust/cmake/RustProject.cmake.in b/source/scripts/rust/cmake/RustProject.cmake.in index c1a52cef58..c61e9f3d7e 100644 --- a/source/scripts/rust/cmake/RustProject.cmake.in +++ b/source/scripts/rust/cmake/RustProject.cmake.in @@ -2,7 +2,7 @@ # WebAssembly project generator by Parra Studios # Generates a WebAssembly project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/typescript/cmake/TypeScriptProject.cmake b/source/scripts/typescript/cmake/TypeScriptProject.cmake index 7d25517ba5..525b083d06 100644 --- a/source/scripts/typescript/cmake/TypeScriptProject.cmake +++ b/source/scripts/typescript/cmake/TypeScriptProject.cmake @@ -2,7 +2,7 @@ # TypeScript project generator by Parra Studios # Generates a typescript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/typescript/cmake/TypeScriptProject.cmake.in b/source/scripts/typescript/cmake/TypeScriptProject.cmake.in index b07786e8cb..55efff8931 100644 --- a/source/scripts/typescript/cmake/TypeScriptProject.cmake.in +++ b/source/scripts/typescript/cmake/TypeScriptProject.cmake.in @@ -2,7 +2,7 @@ # TypeScript project generator by Parra Studios # Generates a typescript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/typescript/cmake/TypeScriptProject.json.in b/source/scripts/typescript/cmake/TypeScriptProject.json.in index f609c81ecc..e709dbb6d7 100644 --- a/source/scripts/typescript/cmake/TypeScriptProject.json.in +++ b/source/scripts/typescript/cmake/TypeScriptProject.json.in @@ -3,7 +3,7 @@ # TypeScript project generator by Parra Studios # Generates a typescript project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/wasm/cmake/WasmProject.cmake b/source/scripts/wasm/cmake/WasmProject.cmake index 776675b044..aa326a7401 100644 --- a/source/scripts/wasm/cmake/WasmProject.cmake +++ b/source/scripts/wasm/cmake/WasmProject.cmake @@ -2,7 +2,7 @@ # WebAssembly project generator by Parra Studios # Generates a WebAssembly project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/scripts/wasm/cmake/WasmProject.cmake.in b/source/scripts/wasm/cmake/WasmProject.cmake.in index b3a3c02653..630c875bea 100644 --- a/source/scripts/wasm/cmake/WasmProject.cmake.in +++ b/source/scripts/wasm/cmake/WasmProject.cmake.in @@ -2,7 +2,7 @@ # WebAssembly project generator by Parra Studios # Generates a WebAssembly project embedded into CMake. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/source/serial/CMakeLists.txt b/source/serial/CMakeLists.txt index 6636295d7d..87de042a14 100644 --- a/source/serial/CMakeLists.txt +++ b/source/serial/CMakeLists.txt @@ -158,7 +158,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/serial/include/serial/serial.h b/source/serial/include/serial/serial.h index 720640c4c6..f10f9ea761 100644 --- a/source/serial/include/serial/serial.h +++ b/source/serial/include/serial/serial.h @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * diff --git a/source/serial/include/serial/serial_handle.h b/source/serial/include/serial/serial_handle.h index fa4bdc66f6..9c049fcbca 100644 --- a/source/serial/include/serial/serial_handle.h +++ b/source/serial/include/serial/serial_handle.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/serial/include/serial/serial_interface.h b/source/serial/include/serial/serial_interface.h index e06b55a169..f83a0af8e8 100644 --- a/source/serial/include/serial/serial_interface.h +++ b/source/serial/include/serial/serial_interface.h @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * diff --git a/source/serial/source/serial.c b/source/serial/source/serial.c index 74bbb01861..7a7e71faba 100644 --- a/source/serial/source/serial.c +++ b/source/serial/source/serial.c @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * @@ -144,7 +144,7 @@ const char *serial_print_info(void) { static const char serial_info[] = "Serial Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef SERIAL_STATIC_DEFINE "Compiled as static library type" diff --git a/source/serials/metacall_serial/CMakeLists.txt b/source/serials/metacall_serial/CMakeLists.txt index 0a981ebd3b..5a11cbc8e5 100644 --- a/source/serials/metacall_serial/CMakeLists.txt +++ b/source/serials/metacall_serial/CMakeLists.txt @@ -158,7 +158,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h b/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h index 5d4f2e119f..d6aece4e79 100644 --- a/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h +++ b/source/serials/metacall_serial/include/metacall_serial/metacall_serial.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -27,8 +27,6 @@ #include <serial/serial_interface.h> -#include <dynlink/dynlink.h> - #ifdef __cplusplus extern "C" { #endif @@ -45,8 +43,6 @@ extern "C" { */ METACALL_SERIAL_API serial_interface metacall_serial_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(metacall_serial_impl_interface_singleton); - /** * @brief * Provide the module information @@ -57,8 +53,6 @@ DYNLINK_SYMBOL_EXPORT(metacall_serial_impl_interface_singleton); */ METACALL_SERIAL_API const char *metacall_serial_print_info(void); -DYNLINK_SYMBOL_EXPORT(metacall_serial_print_info); - #ifdef __cplusplus } #endif diff --git a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl.h b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl.h index 541fe4bd60..8dd25ce64a 100644 --- a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl.h +++ b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl.h @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * diff --git a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_deserialize.h b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_deserialize.h index 6f3d0a3f09..f6324b4412 100644 --- a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_deserialize.h +++ b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_deserialize.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_serialize.h b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_serialize.h index dbe14b5900..21c0eb0601 100644 --- a/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_serialize.h +++ b/source/serials/metacall_serial/include/metacall_serial/metacall_serial_impl_serialize.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/serials/metacall_serial/source/metacall_serial.c b/source/serials/metacall_serial/source/metacall_serial.c index 2bf699644a..70b16af396 100644 --- a/source/serials/metacall_serial/source/metacall_serial.c +++ b/source/serials/metacall_serial/source/metacall_serial.c @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * @@ -32,7 +32,7 @@ const char *metacall_serial_print_info(void) { static const char metacall_serial_info[] = "MetaCall Native Format Serial Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef METACALL_SERIAL_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/serials/metacall_serial/source/metacall_serial_impl.c b/source/serials/metacall_serial/source/metacall_serial_impl.c index 1c69c47c6b..8e48d1e7d5 100644 --- a/source/serials/metacall_serial/source/metacall_serial_impl.c +++ b/source/serials/metacall_serial/source/metacall_serial_impl.c @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * diff --git a/source/serials/metacall_serial/source/metacall_serial_impl_deserialize.c b/source/serials/metacall_serial/source/metacall_serial_impl_deserialize.c index 2487545d71..3f415ade35 100644 --- a/source/serials/metacall_serial/source/metacall_serial_impl_deserialize.c +++ b/source/serials/metacall_serial/source/metacall_serial_impl_deserialize.c @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/serials/metacall_serial/source/metacall_serial_impl_serialize.c b/source/serials/metacall_serial/source/metacall_serial_impl_serialize.c index 93852bbe62..16dd1d2679 100644 --- a/source/serials/metacall_serial/source/metacall_serial_impl_serialize.c +++ b/source/serials/metacall_serial/source/metacall_serial_impl_serialize.c @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -221,7 +221,7 @@ void metacall_serial_impl_serialize_array(value v, char *dest, size_t size, cons (void)format; - /* Calculate sum of all array values lenght */ + /* Calculate sum of all array values length */ for (iterator = 0; iterator < array_size; ++iterator) { value current_value = array_value[iterator]; diff --git a/source/serials/rapid_json_serial/CMakeLists.txt b/source/serials/rapid_json_serial/CMakeLists.txt index c3f1d0d0c8..29fd739aa5 100644 --- a/source/serials/rapid_json_serial/CMakeLists.txt +++ b/source/serials/rapid_json_serial/CMakeLists.txt @@ -191,7 +191,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h index 51e32e3b80..12bfd53432 100644 --- a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h +++ b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -27,8 +27,6 @@ #include <serial/serial_interface.h> -#include <dynlink/dynlink.h> - #ifdef __cplusplus extern "C" { #endif @@ -45,8 +43,6 @@ extern "C" { */ RAPID_JSON_SERIAL_API serial_interface rapid_json_serial_impl_interface_singleton(void); -DYNLINK_SYMBOL_EXPORT(rapid_json_serial_impl_interface_singleton); - /** * @brief * Provide the module information @@ -57,8 +53,6 @@ DYNLINK_SYMBOL_EXPORT(rapid_json_serial_impl_interface_singleton); */ RAPID_JSON_SERIAL_API const char *rapid_json_serial_print_info(void); -DYNLINK_SYMBOL_EXPORT(rapid_json_serial_print_info); - #ifdef __cplusplus } #endif diff --git a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial_impl.h b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial_impl.h index 936bcd34d1..7d7fda83e7 100644 --- a/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial_impl.h +++ b/source/serials/rapid_json_serial/include/rapid_json_serial/rapid_json_serial_impl.h @@ -2,7 +2,7 @@ * Serial Library by Parra Studios * A cross-platform library for managing multiple serialization and deserialization formats. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/serials/rapid_json_serial/source/rapid_json_serial.c b/source/serials/rapid_json_serial/source/rapid_json_serial.c index 12760dca9a..e7671b55a0 100644 --- a/source/serials/rapid_json_serial/source/rapid_json_serial.c +++ b/source/serials/rapid_json_serial/source/rapid_json_serial.c @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * @@ -32,7 +32,7 @@ const char *rapid_json_serial_print_info(void) { static const char rapid_json_serial_info[] = "Rapid JSON Serial Plugin " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef RAPID_JSON_SERIAL_STATIC_DEFINE "Compiled as static library type\n" diff --git a/source/serials/rapid_json_serial/source/rapid_json_serial_impl.cpp b/source/serials/rapid_json_serial/source/rapid_json_serial_impl.cpp index a196b672a6..f46cb09b1b 100644 --- a/source/serials/rapid_json_serial/source/rapid_json_serial_impl.cpp +++ b/source/serials/rapid_json_serial/source/rapid_json_serial_impl.cpp @@ -1,6 +1,6 @@ /* * Serial Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A cross-platform library for managing multiple serialization and deserialization formats. * @@ -12,14 +12,27 @@ #include <log/log.h> -// TODO: RapidJSON seems to be outdated, but we use it meanwhile there's a better solution. -// Here's a patch for some of the bugs in the library: https://github.com/Tencent/rapidjson/issues/1928 +/* Disable warnings from RapidJSON */ +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wstrict-overflow" +#elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-overflow" +#endif #include <rapidjson/document.h> #include <rapidjson/error/en.h> #include <rapidjson/stringbuffer.h> #include <rapidjson/writer.h> +/* Disable warnings from RapidJSON */ +#if defined(__clang__) + #pragma clang diagnostic pop +#elif defined(__GNUC__) + #pragma GCC diagnostic pop +#endif + #include <sstream> /* -- Type Definitions -- */ @@ -41,7 +54,6 @@ static value rapid_json_serial_impl_deserialize_value(const rapidjson::Value *v) /* -- Classes -- */ -// https://techoverflow.net/2020/01/13/how-to-fix-rapidjson-segmentation-faults-when-building-nested-documents/ rapidjson::MemoryPoolAllocator<> rapid_json_allocator; /* -- Methods -- */ @@ -91,9 +103,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) { short s = value_to_short(v); - int i = (int)s; - - json_v->SetInt(i); + json_v->SetInt((int)s); } else if (id == TYPE_INT) { @@ -105,9 +115,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) { long l = value_to_long(v); - log_write("metacall", LOG_LEVEL_WARNING, "Casting long to int64_t (posible incompatible types) in RapidJSON implementation"); - - json_v->SetInt64(l); + json_v->SetInt64((int64_t)l); } else if (id == TYPE_FLOAT) { @@ -127,7 +135,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = value_type_size(v); - rapidjson::SizeType length = size > 0 ? (rapidjson::SizeType)(size - 1) : 0; + rapidjson::SizeType length = size > 0 ? static_cast<rapidjson::SizeType>(size - 1) : 0; json_v->SetString(str, length); } @@ -221,7 +229,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = sizeof(str); - rapidjson::SizeType length = size > 0 ? (rapidjson::SizeType)(size - 1) : 0; + rapidjson::SizeType length = size > 0 ? static_cast<rapidjson::SizeType>(size - 1) : 0; json_v->SetString(str, length); } @@ -232,7 +240,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = sizeof(str); - rapidjson::SizeType length = size > 0 ? (rapidjson::SizeType)(size - 1) : 0; + rapidjson::SizeType length = size > 0 ? static_cast<rapidjson::SizeType>(size - 1) : 0; json_v->SetString(str, length); } @@ -243,7 +251,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = sizeof(str); - rapidjson::SizeType length = size > 0 ? (rapidjson::SizeType)(size - 1) : 0; + rapidjson::SizeType length = size > 0 ? static_cast<rapidjson::SizeType>(size - 1) : 0; json_v->SetString(str, length); } @@ -254,7 +262,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = sizeof(str); - rapidjson::SizeType length = size > 0 ? (rapidjson::SizeType)(size - 1) : 0; + rapidjson::SizeType length = size > 0 ? static_cast<rapidjson::SizeType>(size - 1) : 0; json_v->SetString(str, length); } @@ -267,29 +275,29 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) rapidjson::Value message_member, message_value; static const char message_str[] = "message"; - message_member.SetString(message_str, (rapidjson::SizeType)(sizeof(message_str) - 1)); - message_value.SetString(exception_message(ex), strlen(exception_message(ex))); + message_member.SetString(message_str, static_cast<rapidjson::SizeType>(sizeof(message_str) - 1)); + message_value.SetString(exception_message(ex), static_cast<rapidjson::SizeType>(strlen(exception_message(ex)))); json_map.AddMember(message_member, message_value, rapid_json_allocator); rapidjson::Value label_member, label_value; static const char label_str[] = "label"; - label_member.SetString(label_str, (rapidjson::SizeType)(sizeof(label_str) - 1)); - label_value.SetString(exception_label(ex), strlen(exception_label(ex))); + label_member.SetString(label_str, static_cast<rapidjson::SizeType>(sizeof(label_str) - 1)); + label_value.SetString(exception_label(ex), static_cast<rapidjson::SizeType>(strlen(exception_label(ex)))); json_map.AddMember(label_member, label_value, rapid_json_allocator); rapidjson::Value code_member, code_value; static const char code_str[] = "code"; - code_member.SetString(code_str, (rapidjson::SizeType)(sizeof(code_str) - 1)); + code_member.SetString(code_str, static_cast<rapidjson::SizeType>(sizeof(code_str) - 1)); code_value.SetInt64(exception_error_code(ex)); json_map.AddMember(code_member, code_value, rapid_json_allocator); rapidjson::Value stacktrace_member, stacktrace_value; static const char stacktrace_str[] = "stacktrace"; - stacktrace_member.SetString(stacktrace_str, (rapidjson::SizeType)(sizeof(stacktrace_str) - 1)); - stacktrace_value.SetString(exception_stacktrace(ex), strlen(exception_stacktrace(ex))); + stacktrace_member.SetString(stacktrace_str, static_cast<rapidjson::SizeType>(sizeof(stacktrace_str) - 1)); + stacktrace_value.SetString(exception_stacktrace(ex), static_cast<rapidjson::SizeType>(strlen(exception_stacktrace(ex)))); json_map.AddMember(stacktrace_member, stacktrace_value, rapid_json_allocator); } else if (id == TYPE_THROWABLE) @@ -302,7 +310,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) size_t size = sizeof(str); - rapidjson::SizeType length = (rapidjson::SizeType)(size - 1); + rapidjson::SizeType length = static_cast<rapidjson::SizeType>(size - 1); rapidjson::Value json_member, json_inner_value; @@ -320,7 +328,7 @@ void rapid_json_serial_impl_serialize_value(value v, rapidjson::Value *json_v) std::string s = ostream.str(); - json_v->SetString(s.c_str(), (rapidjson::SizeType)s.length()); + json_v->SetString(s.c_str(), static_cast<rapidjson::SizeType>(s.length())); } else if (id == TYPE_NULL) { @@ -394,6 +402,7 @@ value rapid_json_serial_impl_deserialize_value(const rapidjson::Value *v) { unsigned int ui = v->GetUint(); + /* TODO: Review this, in case of underflow/overflow store it in a bigger type? */ log_write("metacall", LOG_LEVEL_WARNING, "Casting unsigned integer to integer (posible overflow) in RapidJSON implementation"); return value_create_int((int)ui); @@ -402,13 +411,21 @@ value rapid_json_serial_impl_deserialize_value(const rapidjson::Value *v) { int64_t i = v->GetInt64(); + /* TODO: Review this, in case of underflow/overflow store it in a bigger type? */ +#if LONG_MAX < INT64_MAX + log_write("metacall", LOG_LEVEL_WARNING, "Casting long to int (posible overflow) in RapidJSON implementation"); +#endif + return value_create_long((long)i); } else if (v->IsUint64() == true) { uint64_t ui = v->GetUint64(); + /* TODO: Review this, in case of underflow/overflow store it in a bigger type? */ +#if LONG_MAX < UINT64_MAX log_write("metacall", LOG_LEVEL_WARNING, "Casting unsigned long to int (posible overflow) in RapidJSON implementation"); +#endif return value_create_long((long)ui); } diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index eb70ae1c70..2f2e6bb890 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -12,7 +12,7 @@ if("${CMAKE_VERSION}" VERSION_LESS "3.11" AND POLICY CMP0037) set_policy(CMP0037 OLD) endif() -set(GTEST_VERSION 1.11.0) +set(GTEST_VERSION 1.16.0) find_package(GTest ${GTEST_VERSION}) @@ -128,6 +128,7 @@ add_subdirectory(metacall_node_reentrant_test) add_subdirectory(metacall_node_port_test) add_subdirectory(metacall_node_port_await_test) add_subdirectory(metacall_node_port_rs_test) +add_subdirectory(metacall_node_port_c_lib_test) add_subdirectory(metacall_node_python_port_mock_test) add_subdirectory(metacall_node_python_port_ruby_test) add_subdirectory(metacall_node_python_ruby_test) @@ -157,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) @@ -244,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/adt_map_test/CMakeLists.txt b/source/tests/adt_map_test/CMakeLists.txt index 65c947a0cd..0767bcbb2b 100644 --- a/source/tests/adt_map_test/CMakeLists.txt +++ b/source/tests/adt_map_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/adt_map_test/source/adt_map_test.cpp b/source/tests/adt_map_test/source/adt_map_test.cpp index 72124f34d0..24217e3834 100644 --- a/source/tests/adt_map_test/source/adt_map_test.cpp +++ b/source/tests/adt_map_test/source/adt_map_test.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -24,9 +24,13 @@ #include <log/log.h> +#include <vector> + typedef char key_str[7]; static size_t iterator_counter = 0; +static std::vector<int> order_iterate; +static std::vector<int> order_iterator; int map_cb_iterate_str_to_int(map m, map_key key, map_value value, map_cb_iterate_args args) { @@ -34,6 +38,8 @@ int map_cb_iterate_str_to_int(map m, map_key key, map_value value, map_cb_iterat { log_write("metacall", LOG_LEVEL_DEBUG, "%s -> %d", (char *)key, *((int *)(value))); + order_iterate.push_back(*((int *)(value))); + ++iterator_counter; return 0; @@ -108,6 +114,26 @@ TEST_F(adt_map_test, map_int) EXPECT_EQ((size_t)iterator_counter, (size_t)value_array_size * 2); + /* Iterators */ + iterator_counter = 0; + struct map_iterator_type it; + + for (map_iterator_begin(&it, m); map_iterator_end(&it) != 0; map_iterator_next(&it)) + { + char *key = (char *)map_iterator_key(&it); + int *value = (int *)map_iterator_value(&it); + + log_write("metacall", LOG_LEVEL_DEBUG, "[%s -> %d]", (char *)key, *((int *)(value))); + + order_iterator.push_back(*((int *)(value))); + + iterator_counter++; + } + + EXPECT_EQ((size_t)iterator_counter, (size_t)value_array_size * 2); + + EXPECT_EQ((bool)true, (bool)(order_iterator == order_iterate)); + /* Get value */ for (size_t i = 0; i < key_array_size; ++i) { diff --git a/source/tests/adt_map_test/source/main.cpp b/source/tests/adt_map_test/source/main.cpp index 1888b3214a..24fae6af69 100644 --- a/source/tests/adt_map_test/source/main.cpp +++ b/source/tests/adt_map_test/source/main.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/adt_set_test/CMakeLists.txt b/source/tests/adt_set_test/CMakeLists.txt index b56b9e7d9d..a3d3b1c3f0 100644 --- a/source/tests/adt_set_test/CMakeLists.txt +++ b/source/tests/adt_set_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/adt_set_test/source/adt_set_test.cpp b/source/tests/adt_set_test/source/adt_set_test.cpp index 98edb9c550..85c087b9ce 100644 --- a/source/tests/adt_set_test/source/adt_set_test.cpp +++ b/source/tests/adt_set_test/source/adt_set_test.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -27,6 +27,8 @@ typedef char key_str[7]; static size_t iterator_counter = 0; +static std::vector<int> order_iterate; +static std::vector<int> order_iterator; int set_cb_iterate_str_to_int(set s, set_key key, set_value value, set_cb_iterate_args args) { @@ -34,6 +36,8 @@ int set_cb_iterate_str_to_int(set s, set_key key, set_value value, set_cb_iterat { log_write("metacall", LOG_LEVEL_DEBUG, "%s -> %d", (char *)key, *((int *)(value))); + order_iterate.push_back(*((int *)(value))); + ++iterator_counter; return 0; @@ -120,6 +124,26 @@ TEST_F(adt_set_test, DefaultConstructor) EXPECT_EQ((size_t)iterator_counter, (size_t)value_array_size); + /* Iterators */ + iterator_counter = 0; + struct set_iterator_type it; + + for (set_iterator_begin(&it, s); set_iterator_end(&it) != 0; set_iterator_next(&it)) + { + char *key = (char *)set_iterator_key(&it); + int *value = (int *)set_iterator_value(&it); + + log_write("metacall", LOG_LEVEL_DEBUG, "[%s -> %d]", (char *)key, *((int *)(value))); + + order_iterator.push_back(*((int *)(value))); + + iterator_counter++; + } + + EXPECT_EQ((size_t)iterator_counter, (size_t)value_array_size); + + EXPECT_EQ((bool)true, (bool)(order_iterator == order_iterate)); + /* Get value */ for (size_t i = 0; i < key_array_size; ++i) { diff --git a/source/tests/adt_set_test/source/main.cpp b/source/tests/adt_set_test/source/main.cpp index 1888b3214a..24fae6af69 100644 --- a/source/tests/adt_set_test/source/main.cpp +++ b/source/tests/adt_set_test/source/main.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/adt_trie_test/CMakeLists.txt b/source/tests/adt_trie_test/CMakeLists.txt index b59489c704..19babf556b 100644 --- a/source/tests/adt_trie_test/CMakeLists.txt +++ b/source/tests/adt_trie_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) 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 86eb087606..1d9541dc03 100644 --- a/source/tests/adt_trie_test/source/adt_trie_test.cpp +++ b/source/tests/adt_trie_test/source/adt_trie_test.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/adt_trie_test/source/main.cpp b/source/tests/adt_trie_test/source/main.cpp index 1888b3214a..24fae6af69 100644 --- a/source/tests/adt_trie_test/source/main.cpp +++ b/source/tests/adt_trie_test/source/main.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/adt_vector_test/CMakeLists.txt b/source/tests/adt_vector_test/CMakeLists.txt index f01ad35d0e..e454f0266d 100644 --- a/source/tests/adt_vector_test/CMakeLists.txt +++ b/source/tests/adt_vector_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/adt_vector_test/source/adt_vector_test.cpp b/source/tests/adt_vector_test/source/adt_vector_test.cpp index a334471370..816c3bcf59 100644 --- a/source/tests/adt_vector_test/source/adt_vector_test.cpp +++ b/source/tests/adt_vector_test/source/adt_vector_test.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/adt_vector_test/source/main.cpp b/source/tests/adt_vector_test/source/main.cpp index 1888b3214a..24fae6af69 100644 --- a/source/tests/adt_vector_test/source/main.cpp +++ b/source/tests/adt_vector_test/source/main.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/configuration_test/CMakeLists.txt b/source/tests/configuration_test/CMakeLists.txt index 2e9e6d9964..0700e2bf71 100644 --- a/source/tests/configuration_test/CMakeLists.txt +++ b/source/tests/configuration_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/configuration_test/source/configuration_test.cpp b/source/tests/configuration_test/source/configuration_test.cpp index 657f8dff24..056d99493f 100644 --- a/source/tests/configuration_test/source/configuration_test.cpp +++ b/source/tests/configuration_test/source/configuration_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/configuration_test/source/main.cpp b/source/tests/configuration_test/source/main.cpp index 4e6c7d2629..4b3063b2f5 100644 --- a/source/tests/configuration_test/source/main.cpp +++ b/source/tests/configuration_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/detour_test/CMakeLists.txt b/source/tests/detour_test/CMakeLists.txt index b22067a447..06e3ef9794 100644 --- a/source/tests/detour_test/CMakeLists.txt +++ b/source/tests/detour_test/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if detours are enabled -if(NOT OPTION_FORK_SAFE OR NOT OPTION_BUILD_DETOURS OR NOT OPTION_BUILD_DETOURS_FUNCHOOK) +if(NOT OPTION_BUILD_DETOURS OR NOT OPTION_BUILD_DETOURS_PLTHOOK) return() endif() @@ -117,11 +117,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -134,6 +143,14 @@ add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> ) +# +# Define dependencies +# + +add_dependencies(${target} + plthook_detour +) + # # Define test properties # diff --git a/source/tests/detour_test/source/detour_test.cpp b/source/tests/detour_test/source/detour_test.cpp index 3595eda99d..4882867e83 100644 --- a/source/tests/detour_test/source/detour_test.cpp +++ b/source/tests/detour_test/source/detour_test.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -24,6 +24,8 @@ #include <detour/detour.h> +#include <dynlink/dynlink.h> + #include <string.h> class detour_test : public testing::Test @@ -31,27 +33,60 @@ class detour_test : public testing::Test public: }; -static detour_handle handle; +static detour_handle handle = NULL; +static const char *(*trampoline)(void) = NULL; -int hook_function(int x) +int check_detour_hook(const char *(*fp)(void)) { - EXPECT_EQ((int)128, (int)x); + static const char str_without_hook[] = "Detour Library"; + + const char *str = fp(); + + log_write("metacall", LOG_LEVEL_DEBUG, "Check: %s", str); - log_write("metacall", LOG_LEVEL_DEBUG, "Hook function %d", x); + return strncmp(str, str_without_hook, sizeof(str_without_hook) - 1); +} - int (*target_function_ptr)(int) = (int (*)(int))detour_trampoline(handle); +const char *hook_function(void) +{ + static const char str_with_hook[] = "Yeet"; - int result = target_function_ptr(x + 2) + 2; + log_write("metacall", LOG_LEVEL_DEBUG, "HOOK WORKING PROPERLY"); + log_write("metacall", LOG_LEVEL_DEBUG, "Original function: %s", trampoline()); - log_write("metacall", LOG_LEVEL_DEBUG, "Hook function result %d", result); + /* Here we check that we got the correct trampoline implementation (aka the original function) + and we can call it from inside of the body of the hook function */ + EXPECT_EQ((int)0, (int)check_detour_hook(trampoline)); - return result; + return str_with_hook; } -int target_function(int x) +/* TODO: +* This test is not going to work because detour_enumeration does not walk in +* the following sections: +* T Global text symbol +* t Local text symbol +* This funtion we are searching for is stored in: +* 0000000000073630 T test_exported_symbols_from_executable +* 00000000000736e0 t _Z13hook_functionv +* 0000000000072e34 t _Z13hook_functionv.cold +* 0000000000073680 t _Z17check_detour_hookPFPKcvE +* We can find all the sections here: https://en.wikipedia.org/wiki/Nm_(Unix) +* For listing properly all the symbols we should replicate something like +* GNU libc does under the hood for dlsym, which is implemented through do_lookup: +* https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=elf/dl-lookup.c;hb=HEAD +* We will leave this for future versions, including support for GNU hashed symbols. +*/ +#define TODO_TEST_EXPORTED_SYMBOLS_FROM_EXECUTABLE 1 + +#ifdef _WIN32 + #define EXPORT_SYMBOL __declspec(dllexport) +#else + #define EXPORT_SYMBOL __attribute__((visibility("default"))) +#endif + +extern "C" EXPORT_SYMBOL int test_exported_symbols_from_executable(int x) { - EXPECT_EQ((int)130, (int)x); - log_write("metacall", LOG_LEVEL_DEBUG, "Target function %d", x); return x; @@ -59,7 +94,7 @@ int target_function(int x) TEST_F(detour_test, DefaultConstructor) { - static const char name[] = "funchook"; + static const char name[] = "plthook"; /* Initialize log */ EXPECT_EQ((int)0, (int)log_configure("metacall", @@ -71,23 +106,55 @@ TEST_F(detour_test, DefaultConstructor) /* Initialize detour */ EXPECT_EQ((int)0, (int)detour_initialize()); - /* Create detour funchook */ + /* Create detour plthook */ detour d = detour_create(name); - EXPECT_NE((detour)NULL, (detour)d); + ASSERT_NE((detour)NULL, (detour)d); + + EXPECT_STREQ(name, detour_name(d)); + + /* Load detour of detour library */ + handle = detour_load_file(d, NULL); + + ASSERT_NE((detour_handle)NULL, (detour_handle)handle); + + /* Check if it can list exported symbols from executable */ +#ifndef TODO_TEST_EXPORTED_SYMBOLS_FROM_EXECUTABLE + test_exported_symbols_from_executable(3); + + unsigned int position = 0; + const char *fn_name = NULL; + void (**addr)(void) = NULL; + bool found = false; + while (detour_enumerate(d, handle, &position, &fn_name, &addr) == 0) + { + log_write("metacall", LOG_LEVEL_DEBUG, "[%d] %p %s", position, *addr, fn_name); + + if (strcmp("test_exported_symbols_from_executable", fn_name) == 0) + { + found = true; + EXPECT_EQ((void *)(*addr), (void *)(&test_exported_symbols_from_executable)); + break; + } + } - EXPECT_EQ((int)0, (int)strcmp(name, detour_name(d))); + EXPECT_EQ((bool)true, (bool)found); +#endif /* Install detour */ - handle = detour_install(d, (void (*)(void)) & target_function, (void (*)(void)) & hook_function); + union + { + const char *(**trampoline)(void); + void (**ptr)(void); + } cast = { &trampoline }; - EXPECT_NE((detour_handle)NULL, (detour_handle)handle); + ASSERT_EQ((int)0, detour_replace(d, handle, "detour_print_info", (void (*)(void))(&hook_function), cast.ptr)); - /* Call detour, it should call hooked function */ - EXPECT_EQ((int)132, (int)target_function(128)); + /* This must return "Yeet", so when checking the test it should return distinct from 0, then the funtion is properly hooked */ + EXPECT_NE((int)0, (int)check_detour_hook(&detour_print_info)); /* Uninstall detour */ - EXPECT_EQ((int)0, (int)detour_uninstall(d, handle)); + detour_unload(d, handle); /* Clear detour */ EXPECT_EQ((int)0, (int)detour_clear(d)); diff --git a/source/tests/detour_test/source/main.cpp b/source/tests/detour_test/source/main.cpp index d678d80ae7..ccd0ee35a6 100644 --- a/source/tests/detour_test/source/main.cpp +++ b/source/tests/detour_test/source/main.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/dynlink_test/CMakeLists.txt b/source/tests/dynlink_test/CMakeLists.txt index f8375ae695..ae0eabeeea 100644 --- a/source/tests/dynlink_test/CMakeLists.txt +++ b/source/tests/dynlink_test/CMakeLists.txt @@ -97,6 +97,8 @@ target_link_libraries(${target} target_compile_definitions(${target} PRIVATE ${DEFAULT_COMPILE_DEFINITIONS} + + $<$<AND:$<BOOL:${OPTION_BUILD_LOADERS}>,$<BOOL:${OPTION_BUILD_LOADERS_MOCK}>>:DYNLINK_TEST_MOCK_LOADER> ) # @@ -108,13 +110,25 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} + + $<$<AND:$<BOOL:${APPLE}>,$<CXX_COMPILER_ID:AppleClang,Clang>>:-Wl,-export_dynamic> + $<$<CXX_COMPILER_ID:GNU>:-rdynamic> ) # @@ -125,6 +139,16 @@ add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> ) +# +# Define dependencies +# + +if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_MOCK) + add_dependencies(${target} + mock_loader + ) +endif() + # # Define test labels # diff --git a/source/tests/dynlink_test/source/dynlink_test.cpp b/source/tests/dynlink_test/source/dynlink_test.cpp index dc77a7c6b9..0119510cab 100644 --- a/source/tests/dynlink_test/source/dynlink_test.cpp +++ b/source/tests/dynlink_test/source/dynlink_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -28,13 +28,26 @@ #define DYNLINK_TEST_LIBRARY_PATH "DYNLINK_TEST_LIBRARY_PATH" -typedef void (*mock_loader_print_func)(void); +typedef const char *(*mock_loader_print_func)(void); class dynlink_test : public testing::Test { protected: }; +#ifdef _WIN32 + #define EXPORT_SYMBOL __declspec(dllexport) +#else + #define EXPORT_SYMBOL __attribute__((visibility("default"))) +#endif + +extern "C" EXPORT_SYMBOL int function_from_current_executable(void) +{ + log_write("metacall", LOG_LEVEL_INFO, "function_from_current_executable"); + + return 48; +} + TEST_F(dynlink_test, DefaultConstructor) { EXPECT_EQ((int)0, (int)log_configure("metacall", @@ -47,46 +60,122 @@ TEST_F(dynlink_test, DefaultConstructor) log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object extension: %s", dynlink_extension()); + /* Test loading symbols from current process */ { -#if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) + dynlink proc = dynlink_load_self(DYNLINK_FLAGS_BIND_LAZY | DYNLINK_FLAGS_BIND_GLOBAL); + + ASSERT_NE((dynlink)proc, (dynlink)(NULL)); + + dynlink_symbol_addr addr; + + EXPECT_EQ((int)0, dynlink_symbol(proc, "function_from_current_executable", &addr)); + + ASSERT_NE((dynlink_symbol_addr)addr, (dynlink_symbol_addr)NULL); + + int (*fn_ptr)(void) = (int (*)(void))addr; + + EXPECT_EQ((int)48, fn_ptr()); + + EXPECT_EQ((int (*)(void))(&function_from_current_executable), (int (*)(void))fn_ptr); + + dynlink_unload(proc); /* Should do nothing except by freeing the handle */ + } + +#ifdef DYNLINK_TEST_MOCK_LOADER + { + #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) const char library_name[] = "mock_loaderd"; -#else + #else const char library_name[] = "mock_loader"; -#endif + #endif char *path = environment_variable_path_create(DYNLINK_TEST_LIBRARY_PATH, NULL, 0, NULL); - dynlink handle = dynlink_load(path, library_name, DYNLINK_FLAGS_BIND_NOW | DYNLINK_FLAGS_BIND_GLOBAL); + ASSERT_NE((char *)path, (char *)NULL); - environment_variable_path_destroy(path); + /* Test library loading */ + { + dynlink handle = dynlink_load(path, library_name, DYNLINK_FLAGS_BIND_NOW | DYNLINK_FLAGS_BIND_GLOBAL); + + ASSERT_NE(handle, (dynlink)NULL); + + log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object file: %s", dynlink_get_path(handle)); + + EXPECT_STREQ(library_name, dynlink_get_name(handle)); - EXPECT_NE(handle, (dynlink)NULL); + if (handle != NULL) + { + dynlink_symbol_addr mock_loader_print_info_addr; + + EXPECT_EQ((int)0, dynlink_symbol(handle, "mock_loader_print_info", &mock_loader_print_info_addr)); + + if (mock_loader_print_info_addr != NULL) + { + mock_loader_print_func print = (mock_loader_print_func)mock_loader_print_info_addr; - log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object file: %s", dynlink_get_name_impl(handle)); + log_write("metacall", LOG_LEVEL_DEBUG, "Print function: %p", (void *)print); - if (handle != NULL) + log_write("metacall", LOG_LEVEL_DEBUG, "Symbol pointer: %p", (void *)mock_loader_print_info_addr); + + if (mock_loader_print_info_addr != NULL) + { + log_write("metacall", LOG_LEVEL_DEBUG, "Pointer is valid"); + } + + log_write("metacall", LOG_LEVEL_DEBUG, "Print: %s", print()); + } + + dynlink_unload(handle); + } + } + + /* Test loading symbols from absolute path */ { - static dynlink_symbol_addr mock_loader_print_info_addr; + char library_name_platform[PORTABILITY_PATH_SIZE]; + char absolute_path[PORTABILITY_PATH_SIZE]; - EXPECT_EQ((int)0, dynlink_symbol(handle, DYNLINK_SYMBOL_STR("mock_loader_print_info"), &mock_loader_print_info_addr)); + dynlink_platform_name(library_name, library_name_platform); - if (mock_loader_print_info_addr != NULL) - { - mock_loader_print_func print = DYNLINK_SYMBOL_GET(mock_loader_print_info_addr); + portability_path_join(path, strlen(path) + 1, library_name_platform, strlen(library_name_platform) + 1, absolute_path, PORTABILITY_PATH_SIZE); + + dynlink handle = dynlink_load_absolute(absolute_path, DYNLINK_FLAGS_BIND_NOW | DYNLINK_FLAGS_BIND_GLOBAL); - log_write("metacall", LOG_LEVEL_DEBUG, "Print function: %p", (void *)print); + ASSERT_NE(handle, (dynlink)NULL); - log_write("metacall", LOG_LEVEL_DEBUG, "Symbol pointer: %p", (void *)mock_loader_print_info_addr); + log_write("metacall", LOG_LEVEL_DEBUG, "Dynamic linked shared object absolute path: %s", absolute_path); + 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)); - if (DYNLINK_SYMBOL_GET(mock_loader_print_info_addr) != NULL) + EXPECT_STREQ(absolute_path, dynlink_get_path(handle)); + EXPECT_STREQ(library_name, dynlink_get_name(handle)); + + if (handle != NULL) + { + dynlink_symbol_addr mock_loader_print_info_addr; + + EXPECT_EQ((int)0, dynlink_symbol(handle, "mock_loader_print_info", &mock_loader_print_info_addr)); + + if (mock_loader_print_info_addr != NULL) { - log_write("metacall", LOG_LEVEL_DEBUG, "Pointer is valid"); + mock_loader_print_func print = (mock_loader_print_func)mock_loader_print_info_addr; + + log_write("metacall", LOG_LEVEL_DEBUG, "Print function: %p", (void *)print); + + log_write("metacall", LOG_LEVEL_DEBUG, "Symbol pointer: %p", (void *)mock_loader_print_info_addr); + + if (mock_loader_print_info_addr != NULL) + { + log_write("metacall", LOG_LEVEL_DEBUG, "Pointer is valid"); + } + + log_write("metacall", LOG_LEVEL_DEBUG, "Print: %s", print()); } - print(); + dynlink_unload(handle); } - - dynlink_unload(handle); } + + environment_variable_path_destroy(path); } +#endif } diff --git a/source/tests/dynlink_test/source/main.cpp b/source/tests/dynlink_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/dynlink_test/source/main.cpp +++ b/source/tests/dynlink_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/environment_test/CMakeLists.txt b/source/tests/environment_test/CMakeLists.txt index 2b314418be..3472e06a8b 100644 --- a/source/tests/environment_test/CMakeLists.txt +++ b/source/tests/environment_test/CMakeLists.txt @@ -103,11 +103,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/environment_test/source/environment_test.cpp b/source/tests/environment_test/source/environment_test.cpp index 4b484a2422..576dfb28aa 100644 --- a/source/tests/environment_test/source/environment_test.cpp +++ b/source/tests/environment_test/source/environment_test.cpp @@ -2,7 +2,7 @@ * Format Library by Parra Studios * A cross-platform library for supporting platform specific environment features. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/environment_test/source/main.cpp b/source/tests/environment_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/environment_test/source/main.cpp +++ b/source/tests/environment_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/log_custom_test/CMakeLists.txt b/source/tests/log_custom_test/CMakeLists.txt index f79f04b9d2..f46ff859e2 100644 --- a/source/tests/log_custom_test/CMakeLists.txt +++ b/source/tests/log_custom_test/CMakeLists.txt @@ -105,11 +105,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/log_custom_test/source/log_custom_test.cpp b/source/tests/log_custom_test/source/log_custom_test.cpp index 98af5d1b03..f97ebcc6b6 100644 --- a/source/tests/log_custom_test/source/log_custom_test.cpp +++ b/source/tests/log_custom_test/source/log_custom_test.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -25,7 +25,7 @@ #include <log/log_handle.h> #include <log/log_level.h> -static const char format[] = "%.19s #%" PRIuS " %s:%" PRIuS " %s @%s "; +static const char format[] = "%.19s #%" PRIu64 " %s:%" PRIuS " %s @%s "; class log_custom_test : public testing::Test { diff --git a/source/tests/log_custom_test/source/main.cpp b/source/tests/log_custom_test/source/main.cpp index d678d80ae7..ccd0ee35a6 100644 --- a/source/tests/log_custom_test/source/main.cpp +++ b/source/tests/log_custom_test/source/main.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/log_test/CMakeLists.txt b/source/tests/log_test/CMakeLists.txt index dfcb40b5eb..d091de149f 100644 --- a/source/tests/log_test/CMakeLists.txt +++ b/source/tests/log_test/CMakeLists.txt @@ -105,11 +105,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/log_test/source/log_test.cpp b/source/tests/log_test/source/log_test.cpp index 8f2939f742..3e1121bc7a 100644 --- a/source/tests/log_test/source/log_test.cpp +++ b/source/tests/log_test/source/log_test.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/log_test/source/main.cpp b/source/tests/log_test/source/main.cpp index d678d80ae7..ccd0ee35a6 100644 --- a/source/tests/log_test/source/main.cpp +++ b/source/tests/log_test/source/main.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_backtrace_plugin_test/CMakeLists.txt b/source/tests/metacall_backtrace_plugin_test/CMakeLists.txt index 31ff00540d..900355faad 100644 --- a/source/tests/metacall_backtrace_plugin_test/CMakeLists.txt +++ b/source/tests/metacall_backtrace_plugin_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_backtrace_plugin_test/source/main.cpp b/source/tests/metacall_backtrace_plugin_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_backtrace_plugin_test/source/main.cpp +++ b/source/tests/metacall_backtrace_plugin_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_backtrace_plugin_test/source/metacall_backtrace_plugin_test.cpp b/source/tests/metacall_backtrace_plugin_test/source/metacall_backtrace_plugin_test.cpp index 900c8b0a25..ff2844f7ad 100644 --- a/source/tests/metacall_backtrace_plugin_test/source/metacall_backtrace_plugin_test.cpp +++ b/source/tests/metacall_backtrace_plugin_test/source/metacall_backtrace_plugin_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -60,5 +60,5 @@ TEST_F(metacall_backtrace_plugin_test, DefaultConstructor) /* Generate a segmentation fault in order to catch it by backtrace plugin */ EXPECT_DEATH({ badass_function(); }, ""); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_c_lib_test/CMakeLists.txt b/source/tests/metacall_c_lib_test/CMakeLists.txt index 60b3157a2b..d3a3750646 100644 --- a/source/tests/metacall_c_lib_test/CMakeLists.txt +++ b/source/tests/metacall_c_lib_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_c_lib_test/source/main.cpp b/source/tests/metacall_c_lib_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_c_lib_test/source/main.cpp +++ b/source/tests/metacall_c_lib_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 28e940a9b8..1f61c2b179 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 @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_c_metacall_test/CMakeLists.txt b/source/tests/metacall_c_metacall_test/CMakeLists.txt new file mode 100644 index 0000000000..00d36ad944 --- /dev/null +++ b/source/tests/metacall_c_metacall_test/CMakeLists.txt @@ -0,0 +1,160 @@ +# Check if this loader is enabled +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_C OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_C) + return() +endif() + +# +# Executable name and options +# + +# Target name +set(target metacall-c-metacall-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_c_metacall_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}::metacall +) + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + ${DEFAULT_COMPILE_DEFINITIONS} + + METACALL_INCLUDE_DIR="${CMAKE_SOURCE_DIR}/source/metacall/include" + METACALL_API_INCLUDE_DIR="${CMAKE_BINARY_DIR}/source/metacall/include" + METACALL_LIBRARY="${PROJECT_OUTPUT_DIR}" +) + +# +# 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} + c_loader +) + +# +# Define test properties +# + +set_property(TEST ${target} + PROPERTY LABELS ${target} +) + +include(TestEnvironmentVariables) + +test_environment_variables(${target} + "" + ${TESTS_ENVIRONMENT_VARIABLES} +) diff --git a/source/ports/rb_port/source/rb_port.c b/source/tests/metacall_c_metacall_test/source/main.cpp similarity index 66% rename from source/ports/rb_port/source/rb_port.c rename to source/tests/metacall_c_metacall_test/source/main.cpp index 81e52cbcf8..37d4adc23f 100644 --- a/source/ports/rb_port/source/rb_port.c +++ b/source/tests/metacall_c_metacall_test/source/main.cpp @@ -1,8 +1,8 @@ /* - * MetaCall SWIG Wrapper by Parra Studios - * A complete infrastructure for supporting multiple language bindings in MetaCall. + * Loader Library by Parra Studios + * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -18,6 +18,11 @@ * */ -#include <rb_port/rb_port.h> +#include <gtest/gtest.h> -/* ... */ +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/source/tests/metacall_c_metacall_test/source/metacall_c_metacall_test.cpp b/source/tests/metacall_c_metacall_test/source/metacall_c_metacall_test.cpp new file mode 100644 index 0000000000..f26e1471b3 --- /dev/null +++ b/source/tests/metacall_c_metacall_test/source/metacall_c_metacall_test.cpp @@ -0,0 +1,70 @@ +/* + * 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.h> + +class metacall_c_metacall_test : public testing::Test +{ +protected: +}; + +TEST_F(metacall_c_metacall_test, DefaultConstructor) +{ + ASSERT_EQ((int)0, (int)metacall_initialize()); + + ASSERT_EQ((int)0, metacall_execution_path("c", METACALL_INCLUDE_DIR)); + ASSERT_EQ((int)0, metacall_execution_path("c", METACALL_API_INCLUDE_DIR)); + ASSERT_EQ((int)0, metacall_execution_path("c", METACALL_LIBRARY)); + + ASSERT_EQ((int)0, (int)metacall_load_from_package("c", "metacall", NULL)); + + void *ret = metacall("metacall_print_info"); + + ASSERT_EQ((void *)NULL, (void *)ret); + + EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_STRING); + + EXPECT_EQ((int)0, strncmp(metacall_value_to_string(ret), "MetaCall", 8)); + + /* 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(); +} diff --git a/source/tests/metacall_c_test/CMakeLists.txt b/source/tests/metacall_c_test/CMakeLists.txt index da8b42575d..a5c3e0edde 100644 --- a/source/tests/metacall_c_test/CMakeLists.txt +++ b/source/tests/metacall_c_test/CMakeLists.txt @@ -120,11 +120,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_c_test/source/main.cpp b/source/tests/metacall_c_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_c_test/source/main.cpp +++ b/source/tests/metacall_c_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 2aff37a270..9b4bf3f6bc 100644 --- a/source/tests/metacall_c_test/source/metacall_c_test.cpp +++ b/source/tests/metacall_c_test/source/metacall_c_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -41,6 +41,47 @@ 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) +{ + (void)argc; + (void)data; + + /* Get string from pointer */ + 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); + + 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); + + printf("type id %s\n", metacall_value_type_name(string_value)); + 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(); +} + TEST_F(metacall_c_test, DefaultConstructor) { ASSERT_EQ((int)0, (int)metacall_initialize()); @@ -60,6 +101,133 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_value_destroy(ret); + /* https://github.com/metacall/core/issues/570 */ + { + /* void apply_blur_filter(int pixels[], int width, int height) */ + + /* 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]); + } + + /* 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 */ const char *c_dep_scripts[] = { "ffi.c", @@ -116,21 +284,131 @@ 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)); + + void *ret = metacall("compiled_mult_memory", 3, 4); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((int)metacall_value_to_int(ret), (int)12); + + 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); - // EXPECT_EQ((int)0, (int)metacall_load_from_memory("c", c_buffer, sizeof(c_buffer), NULL)); + printf("type id %s\n", metacall_value_type_name(str_value)); + fflush(stdout); - // TODO - // void *ret = metacall("compiled_mult", 3, 4); + /* It chops the string because it has a fixed size from 'asd' */ + EXPECT_STREQ(metacall_value_to_string(str_value), "yee"); - // EXPECT_NE((void *)NULL, (void *)ret); + metacall_value_destroy(str_value); - // EXPECT_EQ((int)metacall_value_to_int(ret), (int)0); + /* It should contain the new string */ + void *new_str = metacall_value_dereference(str_value_ref); - // metacall_value_destroy(ret); + EXPECT_STREQ(metacall_value_to_string(new_str), "hello world"); + + metacall_value_destroy(new_str); + metacall_value_destroy(str_value_ref); + } + + /* 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); + printf("(R) string str %s\n", metacall_value_to_string(str_value)); + fflush(stdout); + + void *args[] = { + str_value_ref_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); + 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 */ { @@ -153,5 +431,5 @@ TEST_F(metacall_c_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_callback_complex_test/CMakeLists.txt b/source/tests/metacall_callback_complex_test/CMakeLists.txt index 2edd78b985..ddf680698a 100644 --- a/source/tests/metacall_callback_complex_test/CMakeLists.txt +++ b/source/tests/metacall_callback_complex_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_callback_complex_test/source/main.cpp b/source/tests/metacall_callback_complex_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_callback_complex_test/source/main.cpp +++ b/source/tests/metacall_callback_complex_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_callback_complex_test/source/metacall_callback_complex_test.cpp b/source/tests/metacall_callback_complex_test/source/metacall_callback_complex_test.cpp index e608f1dcdc..9906b0824e 100644 --- a/source/tests/metacall_callback_complex_test/source/metacall_callback_complex_test.cpp +++ b/source/tests/metacall_callback_complex_test/source/metacall_callback_complex_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -151,5 +151,5 @@ TEST_F(metacall_callback_complex_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_cast_test/CMakeLists.txt b/source/tests/metacall_cast_test/CMakeLists.txt index 73c8f9d984..674a145164 100644 --- a/source/tests/metacall_cast_test/CMakeLists.txt +++ b/source/tests/metacall_cast_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_cast_test/source/main.cpp b/source/tests/metacall_cast_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_cast_test/source/main.cpp +++ b/source/tests/metacall_cast_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_cast_test/source/metacall_cast_test.cpp b/source/tests/metacall_cast_test/source/metacall_cast_test.cpp index 12cd28065d..9b73a35de2 100644 --- a/source/tests/metacall_cast_test/source/metacall_cast_test.cpp +++ b/source/tests/metacall_cast_test/source/metacall_cast_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -106,5 +106,5 @@ TEST_F(metacall_cast_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_clear_test/CMakeLists.txt b/source/tests/metacall_clear_test/CMakeLists.txt index a40a1ebc95..6698be908a 100644 --- a/source/tests/metacall_clear_test/CMakeLists.txt +++ b/source/tests/metacall_clear_test/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if this loader is enabled -if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY) +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_NODE) return() endif() @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -137,6 +146,7 @@ add_test(NAME ${target} add_dependencies(${target} py_loader + node_loader ) # diff --git a/source/tests/metacall_clear_test/source/main.cpp b/source/tests/metacall_clear_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_clear_test/source/main.cpp +++ b/source/tests/metacall_clear_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_clear_test/source/metacall_clear_test.cpp b/source/tests/metacall_clear_test/source/metacall_clear_test.cpp index 8c59a5bab2..3eab668359 100644 --- a/source/tests/metacall_clear_test/source/metacall_clear_test.cpp +++ b/source/tests/metacall_clear_test/source/metacall_clear_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -76,5 +76,51 @@ TEST_F(metacall_clear_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); +/* NodeJS */ +#if defined(OPTION_BUILD_LOADERS_NODE) + { + static const char script1[] = "function greet() { return 1 }\nmodule.exports = { greet }"; + static const char script2[] = "function greet() { return 2 }\nmodule.exports = { greet }"; + static const char script3[] = "function yeet() { return 3 }\nmodule.exports = { yeet }"; + + void *handle1 = NULL; + void *handle2 = NULL; + + void *ret; + + ASSERT_EQ((int)0, (int)metacall_load_from_memory("node", script1, sizeof(script1), &handle1)); + + ret = metacallhv(handle1, "greet", metacall_null_args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((double)1.0, (double)metacall_value_to_double(ret)); + + ASSERT_EQ((int)0, (int)metacall_load_from_memory("node", script2, sizeof(script2), &handle2)); + + ret = metacallhv(handle2, "greet", metacall_null_args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((double)2.0, (double)metacall_value_to_double(ret)); + + metacall_value_destroy(ret); + + // Now load script number 3 into handle number 2 + ASSERT_EQ((int)0, (int)metacall_load_from_memory("node", script3, sizeof(script3), &handle2)); + + ret = metacallhv(handle2, "yeet", metacall_null_args); + + EXPECT_NE((void *)NULL, (void *)ret); + + EXPECT_EQ((double)3.0, (double)metacall_value_to_double(ret)); + + metacall_value_destroy(ret); + + EXPECT_EQ((int)0, (int)metacall_clear(handle1)); + EXPECT_EQ((int)0, (int)metacall_clear(handle2)); + } +#endif /* OPTION_BUILD_LOADERS_NODE */ + + metacall_destroy(); } diff --git a/source/tests/metacall_cli_core_plugin_await_test/CMakeLists.txt b/source/tests/metacall_cli_core_plugin_await_test/CMakeLists.txt index 5c2f4b7390..13284fb395 100644 --- a/source/tests/metacall_cli_core_plugin_await_test/CMakeLists.txt +++ b/source/tests/metacall_cli_core_plugin_await_test/CMakeLists.txt @@ -119,11 +119,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_cli_core_plugin_await_test/source/main.cpp b/source/tests/metacall_cli_core_plugin_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_cli_core_plugin_await_test/source/main.cpp +++ b/source/tests/metacall_cli_core_plugin_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_cli_core_plugin_await_test/source/metacall_cli_core_plugin_await_test.cpp b/source/tests/metacall_cli_core_plugin_await_test/source/metacall_cli_core_plugin_await_test.cpp index 05b98823b6..04461e788e 100644 --- a/source/tests/metacall_cli_core_plugin_await_test/source/metacall_cli_core_plugin_await_test.cpp +++ b/source/tests/metacall_cli_core_plugin_await_test/source/metacall_cli_core_plugin_await_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -123,5 +123,5 @@ TEST_F(metacall_cli_core_plugin_await_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_cli_core_plugin_test/CMakeLists.txt b/source/tests/metacall_cli_core_plugin_test/CMakeLists.txt index 5da0b4cf35..f0ecb936bc 100644 --- a/source/tests/metacall_cli_core_plugin_test/CMakeLists.txt +++ b/source/tests/metacall_cli_core_plugin_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_cli_core_plugin_test/source/main.cpp b/source/tests/metacall_cli_core_plugin_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_cli_core_plugin_test/source/main.cpp +++ b/source/tests/metacall_cli_core_plugin_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_cli_core_plugin_test/source/metacall_cli_core_plugin_test.cpp b/source/tests/metacall_cli_core_plugin_test/source/metacall_cli_core_plugin_test.cpp index ec178460cf..7b116647c6 100644 --- a/source/tests/metacall_cli_core_plugin_test/source/metacall_cli_core_plugin_test.cpp +++ b/source/tests/metacall_cli_core_plugin_test/source/metacall_cli_core_plugin_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -386,5 +386,5 @@ TEST_F(metacall_cli_core_plugin_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_cobol_test/CMakeLists.txt b/source/tests/metacall_cobol_test/CMakeLists.txt index 6dddd7b9f1..3667141bca 100644 --- a/source/tests/metacall_cobol_test/CMakeLists.txt +++ b/source/tests/metacall_cobol_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_cobol_test/source/main.cpp b/source/tests/metacall_cobol_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_cobol_test/source/main.cpp +++ b/source/tests/metacall_cobol_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_cobol_test/source/metacall_cobol_test.cpp b/source/tests/metacall_cobol_test/source/metacall_cobol_test.cpp index 7158b3bb64..5f74c003ce 100644 --- a/source/tests/metacall_cobol_test/source/metacall_cobol_test.cpp +++ b/source/tests/metacall_cobol_test/source/metacall_cobol_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -91,5 +91,5 @@ TEST_F(metacall_cobol_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_configuration_default_test/CMakeLists.txt b/source/tests/metacall_configuration_default_test/CMakeLists.txt index f82aca6df2..8cf0d40070 100644 --- a/source/tests/metacall_configuration_default_test/CMakeLists.txt +++ b/source/tests/metacall_configuration_default_test/CMakeLists.txt @@ -125,11 +125,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_configuration_default_test/source/main.cpp b/source/tests/metacall_configuration_default_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_configuration_default_test/source/main.cpp +++ b/source/tests/metacall_configuration_default_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_configuration_default_test/source/metacall_configuration_default_test.cpp b/source/tests/metacall_configuration_default_test/source/metacall_configuration_default_test.cpp index af04b08dc6..5cee9a0e7d 100644 --- a/source/tests/metacall_configuration_default_test/source/metacall_configuration_default_test.cpp +++ b/source/tests/metacall_configuration_default_test/source/metacall_configuration_default_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -33,5 +33,5 @@ TEST_F(metacall_configuration_default_test, DefaultConstructor) ASSERT_EQ((int)0, (int)metacall_initialize()); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_configuration_exec_path_test/CMakeLists.txt b/source/tests/metacall_configuration_exec_path_test/CMakeLists.txt index da3bc94faf..04c9d805e4 100644 --- a/source/tests/metacall_configuration_exec_path_test/CMakeLists.txt +++ b/source/tests/metacall_configuration_exec_path_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -195,6 +204,49 @@ test_environment_variables(${target} "${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 # diff --git a/source/tests/metacall_configuration_exec_path_test/data/configurations/py_loader.json.in b/source/tests/metacall_configuration_exec_path_test/data/configurations/py_loader.json.in index 4978ee0b2b..02a8e81f9c 100644 --- a/source/tests/metacall_configuration_exec_path_test/data/configurations/py_loader.json.in +++ b/source/tests/metacall_configuration_exec_path_test/data/configurations/py_loader.json.in @@ -1,5 +1,8 @@ { "execution_paths": [ "@PY_EXECUTION_PATH@" - ] + ], + "dependencies": { + "python": ["@Python3_LIBRARY_NAME_PATH@"] + } } diff --git a/source/tests/metacall_configuration_exec_path_test/source/main.cpp b/source/tests/metacall_configuration_exec_path_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_configuration_exec_path_test/source/main.cpp +++ b/source/tests/metacall_configuration_exec_path_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 48d998782e..0219e58aaf 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -49,11 +49,11 @@ 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); } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } 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 0000000000..93ad2822f8 --- /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 0000000000..ca417e6a73 --- /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 0000000000..02a8e81f9c --- /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 0000000000..a34daba892 --- /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 0000000000..5a8d8d1560 --- /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 0000000000..5820341294 --- /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 0000000000..cd56aa446e --- /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_STREQ(metacall_value_to_string(ret), "Python hello_world: test"); + + metacall_value_destroy(ret); + } +#endif /* OPTION_BUILD_LOADERS_PY */ + + metacall_destroy(); +} diff --git a/source/tests/metacall_cs_test/CMakeLists.txt b/source/tests/metacall_cs_test/CMakeLists.txt index f92b705a74..6eb981ca3c 100644 --- a/source/tests/metacall_cs_test/CMakeLists.txt +++ b/source/tests/metacall_cs_test/CMakeLists.txt @@ -113,11 +113,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_cs_test/include/metacall-cs-test/environment.hpp b/source/tests/metacall_cs_test/include/metacall-cs-test/environment.hpp index 0cac3e1fa9..b2efb0121c 100644 --- a/source/tests/metacall_cs_test/include/metacall-cs-test/environment.hpp +++ b/source/tests/metacall_cs_test/include/metacall-cs-test/environment.hpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_cs_test/source/environment.cpp b/source/tests/metacall_cs_test/source/environment.cpp index 1753b9cd5f..acd33b3c52 100644 --- a/source/tests/metacall_cs_test/source/environment.cpp +++ b/source/tests/metacall_cs_test/source/environment.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -40,5 +40,5 @@ void environment::SetUp() void environment::TearDown() { - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_cs_test/source/main.cpp b/source/tests/metacall_cs_test/source/main.cpp index 86fc123742..41f8024b41 100644 --- a/source/tests/metacall_cs_test/source/main.cpp +++ b/source/tests/metacall_cs_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 5e87a637ce..799b24ec00 100644 --- a/source/tests/metacall_cs_test/source/metacall_cs_test.cpp +++ b/source/tests/metacall_cs_test/source/metacall_cs_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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_csharp_function_test/CMakeLists.txt b/source/tests/metacall_csharp_function_test/CMakeLists.txt index 1d641d00d9..0a70cedb5e 100644 --- a/source/tests/metacall_csharp_function_test/CMakeLists.txt +++ b/source/tests/metacall_csharp_function_test/CMakeLists.txt @@ -121,11 +121,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_csharp_function_test/source/main.cpp b/source/tests/metacall_csharp_function_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_csharp_function_test/source/main.cpp +++ b/source/tests/metacall_csharp_function_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_csharp_function_test/source/metacall_csharp_function_test.cpp b/source/tests/metacall_csharp_function_test/source/metacall_csharp_function_test.cpp index aaa0b4e966..541ff5476b 100644 --- a/source/tests/metacall_csharp_function_test/source/metacall_csharp_function_test.cpp +++ b/source/tests/metacall_csharp_function_test/source/metacall_csharp_function_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -75,5 +75,5 @@ TEST_F(metacall_csharp_function_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_csharp_static_class_test/CMakeLists.txt b/source/tests/metacall_csharp_static_class_test/CMakeLists.txt index 6280b8f986..7c2289c3dd 100644 --- a/source/tests/metacall_csharp_static_class_test/CMakeLists.txt +++ b/source/tests/metacall_csharp_static_class_test/CMakeLists.txt @@ -121,11 +121,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_csharp_static_class_test/source/main.cpp b/source/tests/metacall_csharp_static_class_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_csharp_static_class_test/source/main.cpp +++ b/source/tests/metacall_csharp_static_class_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_csharp_static_class_test/source/metacall_csharp_static_class_test.cpp b/source/tests/metacall_csharp_static_class_test/source/metacall_csharp_static_class_test.cpp index 5057a6efbb..bfaf4f744b 100644 --- a/source/tests/metacall_csharp_static_class_test/source/metacall_csharp_static_class_test.cpp +++ b/source/tests/metacall_csharp_static_class_test/source/metacall_csharp_static_class_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -79,5 +79,5 @@ TEST_F(metacall_csharp_static_class_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } 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 0000000000..1a4b07292f --- /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 0000000000..37d4adc23f --- /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 0000000000..90e987e0af --- /dev/null +++ b/source/tests/metacall_cxx_port_test/source/metacall_cxx_port_test.cpp @@ -0,0 +1,196 @@ +/* + * 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> + +class metacall_cxx_port_test : public testing::Test +{ +protected: +}; + +void *cxx_map_test(size_t argc, void *args[], void *data) +{ + metacall::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::metacall_value_create_null(); +} + +void *cxx_array_test(size_t argc, void *args[], void *data) +{ + metacall::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::metacall_value_create_null(); +} + +void *cxx_map_array_test(size_t argc, void *args[], void *data) +{ + metacall::map<std::string, metacall::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::metacall_value_create_null(); +} + +// TODO: +/* +void *cxx_recursive_map_test(size_t argc, void *args[], void *data) +{ + metacall::map<std::string, metacall::map<std::string, float>> m(args[0]); + + (void)argc; + (void)data; + + EXPECT_EQ((float)m["hello"]["world"], (float)4.0f); + + printf("hello => %f\n", m["hello"]["world"]); + fflush(stdout); + + return metacall_value_create_null(); +} +*/ + +void *cxx_float_int_int_test(size_t argc, void *args[], void *data) +{ + metacall::value<int> a0(args[0]); + metacall::value<int> a1(args[1]); + + (void)argc; + (void)data; + + EXPECT_EQ(a0.to_value(), 7); + EXPECT_EQ(a1.to_value(), 8); + + return metacall::metacall_value_create_float(3.0f); +} + +TEST_F(metacall_cxx_port_test, DefaultConstructor) +{ + ASSERT_EQ((int)0, (int)metacall::metacall_initialize()); + + { + metacall::map<std::string, float> m = { + { "hello", 3.0f }, + { "world", 4.0f } + }; + + metacall::metacall_register("cxx_map_test", cxx_map_test, NULL, metacall::METACALL_NULL, 1, metacall::METACALL_MAP); + + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_map_test", m)); + } + + { + metacall::array a(3, 4.0f); + + metacall::metacall_register("cxx_array_test", cxx_array_test, NULL, metacall::METACALL_NULL, 1, metacall::METACALL_ARRAY); + + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_array_test", a)); + } + + { + metacall::map<std::string, metacall::array> m = { + { "includes", metacall::array("/a/path", "/another/path") }, + { "libraries", metacall::array("/a/path", "/another/path") } + }; + + metacall::metacall_register("cxx_map_array_test", cxx_map_array_test, NULL, metacall::METACALL_NULL, 1, metacall::METACALL_MAP); + + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_map_array_test", m)); + } + + // TODO: + /* + { + metacall::map<std::string, metacall::map<std::string, float>> m = { + { "hello", { "world", 4.0f } } + }; + + metacall::metacall_register("cxx_recursive_map_test", cxx_recursive_map_test, NULL, metacall::METACALL_NULL, 1, metacall::METACALL_MAP); + + EXPECT_EQ(nullptr, metacall::metacall<std::nullptr_t>("cxx_recursive_map_test", m)); + } + */ + + { + metacall::metacall_register("cxx_float_int_int_test", cxx_float_int_int_test, NULL, metacall::METACALL_FLOAT, 2, metacall::METACALL_INT, metacall::METACALL_INT); + + EXPECT_EQ(3.0f, metacall::metacall<float>("cxx_float_int_int_test", 7, 8)); + } + + /* Print inspect information */ + { + size_t size = 0; + + metacall::metacall_allocator_std_type std_ctx = { &std::malloc, &std::realloc, &std::free }; + + void *allocator = metacall_allocator_create(metacall::METACALL_ALLOCATOR_STD, (void *)&std_ctx); + + char *inspect_str = metacall::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::metacall_allocator_free(allocator, inspect_str); + + metacall::metacall_allocator_destroy(allocator); + } + + metacall::metacall_destroy(); +} diff --git a/source/tests/metacall_depends_test/CMakeLists.txt b/source/tests/metacall_depends_test/CMakeLists.txt index c94dbeae7d..46fe418c77 100644 --- a/source/tests/metacall_depends_test/CMakeLists.txt +++ b/source/tests/metacall_depends_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_depends_test/source/main.cpp b/source/tests/metacall_depends_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_depends_test/source/main.cpp +++ b/source/tests/metacall_depends_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_depends_test/source/metacall_depends_test.cpp b/source/tests/metacall_depends_test/source/metacall_depends_test.cpp index 69fff39b43..4ec81006c5 100644 --- a/source/tests/metacall_depends_test/source/metacall_depends_test.cpp +++ b/source/tests/metacall_depends_test/source/metacall_depends_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -82,5 +82,5 @@ TEST_F(metacall_depends_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_distributable_test/CMakeLists.txt b/source/tests/metacall_distributable_test/CMakeLists.txt index bf924ad614..07d5581616 100644 --- a/source/tests/metacall_distributable_test/CMakeLists.txt +++ b/source/tests/metacall_distributable_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_distributable_test/source/main.cpp b/source/tests/metacall_distributable_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_distributable_test/source/main.cpp +++ b/source/tests/metacall_distributable_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 03300dbb6b..30b2033cb5 100644 --- a/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp +++ b/source/tests/metacall_distributable_test/source/metacall_distributable_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -276,5 +276,5 @@ TEST_F(metacall_distributable_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_C */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ducktype_test/CMakeLists.txt b/source/tests/metacall_ducktype_test/CMakeLists.txt index 61d3ac4bfa..c8d507e6f0 100644 --- a/source/tests/metacall_ducktype_test/CMakeLists.txt +++ b/source/tests/metacall_ducktype_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ducktype_test/source/main.cpp b/source/tests/metacall_ducktype_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ducktype_test/source/main.cpp +++ b/source/tests/metacall_ducktype_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 4f404762e2..0b8e2e2e84 100644 --- a/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp +++ b/source/tests/metacall_ducktype_test/source/metacall_ducktype_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -386,5 +386,5 @@ TEST_F(metacall_ducktype_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_JS */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_duplicated_handle_test/CMakeLists.txt b/source/tests/metacall_duplicated_handle_test/CMakeLists.txt index c86f54169b..35032c7c5e 100644 --- a/source/tests/metacall_duplicated_handle_test/CMakeLists.txt +++ b/source/tests/metacall_duplicated_handle_test/CMakeLists.txt @@ -110,11 +110,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_duplicated_handle_test/source/main.cpp b/source/tests/metacall_duplicated_handle_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_duplicated_handle_test/source/main.cpp +++ b/source/tests/metacall_duplicated_handle_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_duplicated_handle_test/source/metacall_duplicated_handle_test.cpp b/source/tests/metacall_duplicated_handle_test/source/metacall_duplicated_handle_test.cpp index 370c3e5659..ebd9e57322 100644 --- a/source/tests/metacall_duplicated_handle_test/source/metacall_duplicated_handle_test.cpp +++ b/source/tests/metacall_duplicated_handle_test/source/metacall_duplicated_handle_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -105,5 +105,5 @@ TEST_F(metacall_duplicated_handle_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_duplicated_symbols_test/CMakeLists.txt b/source/tests/metacall_duplicated_symbols_test/CMakeLists.txt index c539070787..c5612d9658 100644 --- a/source/tests/metacall_duplicated_symbols_test/CMakeLists.txt +++ b/source/tests/metacall_duplicated_symbols_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_duplicated_symbols_test/source/main.cpp b/source/tests/metacall_duplicated_symbols_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_duplicated_symbols_test/source/main.cpp +++ b/source/tests/metacall_duplicated_symbols_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_duplicated_symbols_test/source/metacall_duplicated_symbols_test.cpp b/source/tests/metacall_duplicated_symbols_test/source/metacall_duplicated_symbols_test.cpp index 26ce8456a9..07fb659c97 100644 --- a/source/tests/metacall_duplicated_symbols_test/source/metacall_duplicated_symbols_test.cpp +++ b/source/tests/metacall_duplicated_symbols_test/source/metacall_duplicated_symbols_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -155,5 +155,5 @@ TEST_F(metacall_duplicated_symbols_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY + OPTION_BUILD_LOADERS_RB */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_dynlink_path_test/CMakeLists.txt b/source/tests/metacall_dynlink_path_test/CMakeLists.txt index ecc76c6f7c..c1c9a76c42 100644 --- a/source/tests/metacall_dynlink_path_test/CMakeLists.txt +++ b/source/tests/metacall_dynlink_path_test/CMakeLists.txt @@ -111,11 +111,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_dynlink_path_test/source/main.cpp b/source/tests/metacall_dynlink_path_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_dynlink_path_test/source/main.cpp +++ b/source/tests/metacall_dynlink_path_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_dynlink_path_test/source/metacall_dynlink_path_test.cpp b/source/tests/metacall_dynlink_path_test/source/metacall_dynlink_path_test.cpp index 645b93dad7..a989448f45 100644 --- a/source/tests/metacall_dynlink_path_test/source/metacall_dynlink_path_test.cpp +++ b/source/tests/metacall_dynlink_path_test/source/metacall_dynlink_path_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -33,7 +33,7 @@ TEST_F(metacall_dynlink_path_test, DefaultConstructor) { metacall_print_info(); - dynlink_library_path_str path; + dynlink_path path; const char name[] = "metacall" #if (!defined(NDEBUG) || defined(DEBUG) || defined(_DEBUG) || defined(__DEBUG) || defined(__DEBUG__)) diff --git a/source/tests/metacall_ext_test/CMakeLists.txt b/source/tests/metacall_ext_test/CMakeLists.txt index e75e6ff9f4..3c6b986981 100644 --- a/source/tests/metacall_ext_test/CMakeLists.txt +++ b/source/tests/metacall_ext_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ext_test/source/main.cpp b/source/tests/metacall_ext_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_ext_test/source/main.cpp +++ b/source/tests/metacall_ext_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ext_test/source/metacall_ext_test.cpp b/source/tests/metacall_ext_test/source/metacall_ext_test.cpp index 4a15017287..dde1efd0f7 100644 --- a/source/tests/metacall_ext_test/source/metacall_ext_test.cpp +++ b/source/tests/metacall_ext_test/source/metacall_ext_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -75,5 +75,5 @@ TEST_F(metacall_ext_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_file_fail_test/CMakeLists.txt b/source/tests/metacall_file_fail_test/CMakeLists.txt index e58b57b699..ab6236fe16 100644 --- a/source/tests/metacall_file_fail_test/CMakeLists.txt +++ b/source/tests/metacall_file_fail_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_file_fail_test/source/main.cpp b/source/tests/metacall_file_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_file_fail_test/source/main.cpp +++ b/source/tests/metacall_file_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_file_fail_test/source/metacall_file_fail_test.cpp b/source/tests/metacall_file_fail_test/source/metacall_file_fail_test.cpp index ce3a62f7b7..426e44002d 100644 --- a/source/tests/metacall_file_fail_test/source/metacall_file_fail_test.cpp +++ b/source/tests/metacall_file_fail_test/source/metacall_file_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -69,5 +69,5 @@ TEST_F(metacall_file_fail_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_file_glob_test/CMakeLists.txt b/source/tests/metacall_file_glob_test/CMakeLists.txt index fde9870d65..ffc5a1c274 100644 --- a/source/tests/metacall_file_glob_test/CMakeLists.txt +++ b/source/tests/metacall_file_glob_test/CMakeLists.txt @@ -119,11 +119,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_file_glob_test/source/main.cpp b/source/tests/metacall_file_glob_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_file_glob_test/source/main.cpp +++ b/source/tests/metacall_file_glob_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_file_glob_test/source/metacall_file_glob_test.cpp b/source/tests/metacall_file_glob_test/source/metacall_file_glob_test.cpp index 23edddd061..85377d72d6 100644 --- a/source/tests/metacall_file_glob_test/source/metacall_file_glob_test.cpp +++ b/source/tests/metacall_file_glob_test/source/metacall_file_glob_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -70,5 +70,5 @@ TEST_F(metacall_file_glob_test, DefaultConstructor) metacall_allocator_destroy(config_allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_file_test/CMakeLists.txt b/source/tests/metacall_file_test/CMakeLists.txt index ad378539d8..9dd2a4fb04 100644 --- a/source/tests/metacall_file_test/CMakeLists.txt +++ b/source/tests/metacall_file_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_file_test/source/main.cpp b/source/tests/metacall_file_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_file_test/source/main.cpp +++ b/source/tests/metacall_file_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_file_test/source/metacall_file_test.cpp b/source/tests/metacall_file_test/source/metacall_file_test.cpp index 029e8f0f6b..15658125fd 100644 --- a/source/tests/metacall_file_test/source/metacall_file_test.cpp +++ b/source/tests/metacall_file_test/source/metacall_file_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_file_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_fork_test/CMakeLists.txt b/source/tests/metacall_fork_test/CMakeLists.txt index 34ebb8a125..90c96bdef3 100644 --- a/source/tests/metacall_fork_test/CMakeLists.txt +++ b/source/tests/metacall_fork_test/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if detours are enabled -if(NOT OPTION_BUILD_DETOURS OR NOT OPTION_FORK_SAFE) +if(NOT OPTION_FORK_SAFE OR NOT OPTION_BUILD_DETOURS) return() endif() @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -128,7 +137,7 @@ add_test(NAME ${target} # add_dependencies(${target} - funchook_detour + plthook_detour ) # diff --git a/source/tests/metacall_fork_test/source/main.cpp b/source/tests/metacall_fork_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_fork_test/source/main.cpp +++ b/source/tests/metacall_fork_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_fork_test/source/metacall_fork_test.cpp b/source/tests/metacall_fork_test/source/metacall_fork_test.cpp index 07c9e87348..ab784ff942 100644 --- a/source/tests/metacall_fork_test/source/metacall_fork_test.cpp +++ b/source/tests/metacall_fork_test/source/metacall_fork_test.cpp @@ -1,6 +1,6 @@ /* * MetaCall Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A library for providing a foreign function interface calls. * @@ -102,10 +102,7 @@ pid_t fork() if (result == RTL_CLONE_PARENT) { - HANDLE me = GetCurrentProcess(); - pid_t child_pid; - - child_pid = GetProcessId(process_info.Process); + pid_t child_pid = GetProcessId(process_info.Process); ResumeThread(process_info.Thread); CloseHandle(process_info.Process); @@ -115,7 +112,7 @@ pid_t fork() } else if (result == RTL_CLONE_CHILD) { - /* fix stdio */ + /* Fix stdio */ AllocConsole(); return 0; } @@ -169,5 +166,5 @@ TEST_F(metacall_fork_test, DefaultConstructor) EXPECT_EQ((int)1, (int)pre_callback_fired); EXPECT_EQ((int)1, (int)post_callback_fired); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_function_test/CMakeLists.txt b/source/tests/metacall_function_test/CMakeLists.txt index ad6e4fe584..9ac6fe47dc 100644 --- a/source/tests/metacall_function_test/CMakeLists.txt +++ b/source/tests/metacall_function_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_function_test/source/main.cpp b/source/tests/metacall_function_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_function_test/source/main.cpp +++ b/source/tests/metacall_function_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 60c52efb1b..8b837151a1 100644 --- a/source/tests/metacall_function_test/source/metacall_function_test.cpp +++ b/source/tests/metacall_function_test/source/metacall_function_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -272,5 +272,5 @@ TEST_F(metacall_function_test, DefaultConstructor) metacall_value_destroy(c_callback_factorial_impl_value); metacall_value_destroy(c_callback_factorial_value); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_handle_export_test/CMakeLists.txt b/source/tests/metacall_handle_export_test/CMakeLists.txt index d734ebe09f..fb1a708563 100644 --- a/source/tests/metacall_handle_export_test/CMakeLists.txt +++ b/source/tests/metacall_handle_export_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_handle_export_test/source/main.cpp b/source/tests/metacall_handle_export_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_handle_export_test/source/main.cpp +++ b/source/tests/metacall_handle_export_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_handle_export_test/source/metacall_handle_export_test.cpp b/source/tests/metacall_handle_export_test/source/metacall_handle_export_test.cpp index 0c5fc5773d..3d1afe184a 100644 --- a/source/tests/metacall_handle_export_test/source/metacall_handle_export_test.cpp +++ b/source/tests/metacall_handle_export_test/source/metacall_handle_export_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -139,5 +139,5 @@ TEST_F(metacall_handle_export_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_handle_get_test/CMakeLists.txt b/source/tests/metacall_handle_get_test/CMakeLists.txt index dd5aa471e4..c99af8c34e 100644 --- a/source/tests/metacall_handle_get_test/CMakeLists.txt +++ b/source/tests/metacall_handle_get_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_handle_get_test/source/main.cpp b/source/tests/metacall_handle_get_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_handle_get_test/source/main.cpp +++ b/source/tests/metacall_handle_get_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 c1d25836cf..2e80130384 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -158,5 +158,5 @@ TEST_F(metacall_handle_get_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_init_fini_test/CMakeLists.txt b/source/tests/metacall_init_fini_test/CMakeLists.txt index 86f4671052..c757cffb72 100644 --- a/source/tests/metacall_init_fini_test/CMakeLists.txt +++ b/source/tests/metacall_init_fini_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_init_fini_test/source/main.cpp b/source/tests/metacall_init_fini_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_init_fini_test/source/main.cpp +++ b/source/tests/metacall_init_fini_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_init_fini_test/source/metacall_init_fini_test.cpp b/source/tests/metacall_init_fini_test/source/metacall_init_fini_test.cpp index 2290009dd3..b7c64132b2 100644 --- a/source/tests/metacall_init_fini_test/source/metacall_init_fini_test.cpp +++ b/source/tests/metacall_init_fini_test/source/metacall_init_fini_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -55,5 +55,5 @@ TEST_F(metacall_init_fini_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_initialize_destroy_multiple_node_test/CMakeLists.txt b/source/tests/metacall_initialize_destroy_multiple_node_test/CMakeLists.txt index b91de9c5cf..9b06663fda 100644 --- a/source/tests/metacall_initialize_destroy_multiple_node_test/CMakeLists.txt +++ b/source/tests/metacall_initialize_destroy_multiple_node_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_initialize_destroy_multiple_node_test/source/main.cpp b/source/tests/metacall_initialize_destroy_multiple_node_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_initialize_destroy_multiple_node_test/source/main.cpp +++ b/source/tests/metacall_initialize_destroy_multiple_node_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_initialize_destroy_multiple_node_test/source/metacall_initialize_destroy_multiple_node_test.cpp b/source/tests/metacall_initialize_destroy_multiple_node_test/source/metacall_initialize_destroy_multiple_node_test.cpp index 12d008293e..3435254d1f 100644 --- a/source/tests/metacall_initialize_destroy_multiple_node_test/source/metacall_initialize_destroy_multiple_node_test.cpp +++ b/source/tests/metacall_initialize_destroy_multiple_node_test/source/metacall_initialize_destroy_multiple_node_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -51,13 +51,13 @@ TEST_F(metacall_initialize_destroy_multiple_node_test, DefaultConstructor) ASSERT_EQ((int)0, (int)metacall_is_initialized(tag)); - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); ASSERT_EQ((int)1, (int)metacall_is_initialized(tag)); } #endif /* OPTION_BUILD_LOADERS_NODE */ - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_initialize_destroy_multiple_test/CMakeLists.txt b/source/tests/metacall_initialize_destroy_multiple_test/CMakeLists.txt index 1fbd5c0e48..3424ea8817 100644 --- a/source/tests/metacall_initialize_destroy_multiple_test/CMakeLists.txt +++ b/source/tests/metacall_initialize_destroy_multiple_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_initialize_destroy_multiple_test/source/main.cpp b/source/tests/metacall_initialize_destroy_multiple_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_initialize_destroy_multiple_test/source/main.cpp +++ b/source/tests/metacall_initialize_destroy_multiple_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_initialize_destroy_multiple_test/source/metacall_initialize_destroy_multiple_test.cpp b/source/tests/metacall_initialize_destroy_multiple_test/source/metacall_initialize_destroy_multiple_test.cpp index df51f5d946..8a57d13521 100644 --- a/source/tests/metacall_initialize_destroy_multiple_test/source/metacall_initialize_destroy_multiple_test.cpp +++ b/source/tests/metacall_initialize_destroy_multiple_test/source/metacall_initialize_destroy_multiple_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -51,13 +51,13 @@ TEST_F(metacall_initialize_destroy_multiple_test, DefaultConstructor) ASSERT_EQ((int)0, (int)metacall_is_initialized(tag)); - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); ASSERT_EQ((int)1, (int)metacall_is_initialized(tag)); } #endif /* OPTION_BUILD_LOADERS_MOCK */ - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_initialize_ex_test/CMakeLists.txt b/source/tests/metacall_initialize_ex_test/CMakeLists.txt index 18d0f1e580..714d7ce5b3 100644 --- a/source/tests/metacall_initialize_ex_test/CMakeLists.txt +++ b/source/tests/metacall_initialize_ex_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_initialize_ex_test/source/main.cpp b/source/tests/metacall_initialize_ex_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_initialize_ex_test/source/main.cpp +++ b/source/tests/metacall_initialize_ex_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_initialize_ex_test/source/metacall_initialize_ex_test.cpp b/source/tests/metacall_initialize_ex_test/source/metacall_initialize_ex_test.cpp index 8c9e2930b6..d2d9a2ce0a 100644 --- a/source/tests/metacall_initialize_ex_test/source/metacall_initialize_ex_test.cpp +++ b/source/tests/metacall_initialize_ex_test/source/metacall_initialize_ex_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -61,5 +61,5 @@ TEST_F(metacall_initialize_ex_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_MOCK */ - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_initialize_test/CMakeLists.txt b/source/tests/metacall_initialize_test/CMakeLists.txt index 2d231d6161..e66bf472e5 100644 --- a/source/tests/metacall_initialize_test/CMakeLists.txt +++ b/source/tests/metacall_initialize_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_initialize_test/source/main.cpp b/source/tests/metacall_initialize_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_initialize_test/source/main.cpp +++ b/source/tests/metacall_initialize_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_initialize_test/source/metacall_initialize_test.cpp b/source/tests/metacall_initialize_test/source/metacall_initialize_test.cpp index ba4ab42b94..598f6f1ea6 100644 --- a/source/tests/metacall_initialize_test/source/metacall_initialize_test.cpp +++ b/source/tests/metacall_initialize_test/source/metacall_initialize_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -49,5 +49,5 @@ TEST_F(metacall_initialize_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_MOCK */ - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_inspect_test/CMakeLists.txt b/source/tests/metacall_inspect_test/CMakeLists.txt index 7f5664fbb8..8a97a0c8b8 100644 --- a/source/tests/metacall_inspect_test/CMakeLists.txt +++ b/source/tests/metacall_inspect_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_inspect_test/source/main.cpp b/source/tests/metacall_inspect_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_inspect_test/source/main.cpp +++ b/source/tests/metacall_inspect_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_inspect_test/source/metacall_inspect_test.cpp b/source/tests/metacall_inspect_test/source/metacall_inspect_test.cpp index 06b1c220b8..36e95f5f7d 100644 --- a/source/tests/metacall_inspect_test/source/metacall_inspect_test.cpp +++ b/source/tests/metacall_inspect_test/source/metacall_inspect_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -134,5 +134,5 @@ TEST_F(metacall_inspect_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_integration_test/CMakeLists.txt b/source/tests/metacall_integration_test/CMakeLists.txt index b3236cb020..bf2cc13b9f 100644 --- a/source/tests/metacall_integration_test/CMakeLists.txt +++ b/source/tests/metacall_integration_test/CMakeLists.txt @@ -113,11 +113,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_integration_test/include/metacall-integration-test/environment.hpp b/source/tests/metacall_integration_test/include/metacall-integration-test/environment.hpp index 0cac3e1fa9..b2efb0121c 100644 --- a/source/tests/metacall_integration_test/include/metacall-integration-test/environment.hpp +++ b/source/tests/metacall_integration_test/include/metacall-integration-test/environment.hpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_integration_test/source/environment.cpp b/source/tests/metacall_integration_test/source/environment.cpp index 8ac160cf2e..810c4af687 100644 --- a/source/tests/metacall_integration_test/source/environment.cpp +++ b/source/tests/metacall_integration_test/source/environment.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -36,5 +36,5 @@ void environment::SetUp() void environment::TearDown() { - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_integration_test/source/main.cpp b/source/tests/metacall_integration_test/source/main.cpp index 4f69071517..7205061c4c 100644 --- a/source/tests/metacall_integration_test/source/main.cpp +++ b/source/tests/metacall_integration_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_integration_test/source/metacall_integration_test.cpp b/source/tests/metacall_integration_test/source/metacall_integration_test.cpp index 637163e982..629f2b6672 100644 --- a/source/tests/metacall_integration_test/source/metacall_integration_test.cpp +++ b/source/tests/metacall_integration_test/source/metacall_integration_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for dynamic loading and linking shared objects at run-time. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_invalid_loader_test/CMakeLists.txt b/source/tests/metacall_invalid_loader_test/CMakeLists.txt index 3d0941cbaf..cef1167c5a 100644 --- a/source/tests/metacall_invalid_loader_test/CMakeLists.txt +++ b/source/tests/metacall_invalid_loader_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_invalid_loader_test/source/main.cpp b/source/tests/metacall_invalid_loader_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_invalid_loader_test/source/main.cpp +++ b/source/tests/metacall_invalid_loader_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_invalid_loader_test/source/metacall_invalid_loader_test.cpp b/source/tests/metacall_invalid_loader_test/source/metacall_invalid_loader_test.cpp index 92edc0f2d5..3ae84d1469 100644 --- a/source/tests/metacall_invalid_loader_test/source/metacall_invalid_loader_test.cpp +++ b/source/tests/metacall_invalid_loader_test/source/metacall_invalid_loader_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -48,5 +48,5 @@ TEST_F(metacall_invalid_loader_test, DefaultConstructor) ASSERT_EQ((int)1, (int)metacall_is_initialized("invalid")); - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_java_test/CMakeLists.txt b/source/tests/metacall_java_test/CMakeLists.txt index b7e52cab42..fb814afc1f 100644 --- a/source/tests/metacall_java_test/CMakeLists.txt +++ b/source/tests/metacall_java_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_java_test/source/main.cpp b/source/tests/metacall_java_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_java_test/source/main.cpp +++ b/source/tests/metacall_java_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 c934cd1739..5eb6141cc5 100644 --- a/source/tests/metacall_java_test/source/metacall_java_test.cpp +++ b/source/tests/metacall_java_test/source/metacall_java_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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"); @@ -412,5 +412,5 @@ TEST_F(metacall_java_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_julia_test/CMakeLists.txt b/source/tests/metacall_julia_test/CMakeLists.txt index 701fb1b89e..0bfe22f233 100644 --- a/source/tests/metacall_julia_test/CMakeLists.txt +++ b/source/tests/metacall_julia_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_julia_test/source/main.cpp b/source/tests/metacall_julia_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_julia_test/source/main.cpp +++ b/source/tests/metacall_julia_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_julia_test/source/metacall_julia_test.cpp b/source/tests/metacall_julia_test/source/metacall_julia_test.cpp index 1b9e21cdf1..d85bd9ad0d 100644 --- a/source/tests/metacall_julia_test/source/metacall_julia_test.cpp +++ b/source/tests/metacall_julia_test/source/metacall_julia_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -98,5 +98,5 @@ TEST_F(metacall_julia_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_library_path_without_env_vars_test/CMakeLists.txt b/source/tests/metacall_library_path_without_env_vars_test/CMakeLists.txt index 1bc31a11ae..33428a51b8 100644 --- a/source/tests/metacall_library_path_without_env_vars_test/CMakeLists.txt +++ b/source/tests/metacall_library_path_without_env_vars_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_library_path_without_env_vars_test/source/main.cpp b/source/tests/metacall_library_path_without_env_vars_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_library_path_without_env_vars_test/source/main.cpp +++ b/source/tests/metacall_library_path_without_env_vars_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_library_path_without_env_vars_test/source/metacall_library_path_without_env_vars_test.cpp b/source/tests/metacall_library_path_without_env_vars_test/source/metacall_library_path_without_env_vars_test.cpp index a64b4464c8..f971670af2 100644 --- a/source/tests/metacall_library_path_without_env_vars_test/source/metacall_library_path_without_env_vars_test.cpp +++ b/source/tests/metacall_library_path_without_env_vars_test/source/metacall_library_path_without_env_vars_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -45,5 +45,5 @@ TEST_F(metacall_library_path_without_env_vars_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_MOCK */ - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_llvm_test/CMakeLists.txt b/source/tests/metacall_llvm_test/CMakeLists.txt index acc723fdc3..cbe63c93f1 100644 --- a/source/tests/metacall_llvm_test/CMakeLists.txt +++ b/source/tests/metacall_llvm_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_llvm_test/source/main.cpp b/source/tests/metacall_llvm_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_llvm_test/source/main.cpp +++ b/source/tests/metacall_llvm_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_llvm_test/source/metacall_llvm_test.cpp b/source/tests/metacall_llvm_test/source/metacall_llvm_test.cpp index 446161e609..fe1e961250 100644 --- a/source/tests/metacall_llvm_test/source/metacall_llvm_test.cpp +++ b/source/tests/metacall_llvm_test/source/metacall_llvm_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -99,5 +99,5 @@ TEST_F(metacall_llvm_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_configuration_fail_test/CMakeLists.txt b/source/tests/metacall_load_configuration_fail_test/CMakeLists.txt index d25581f20a..c49bf0e10d 100644 --- a/source/tests/metacall_load_configuration_fail_test/CMakeLists.txt +++ b/source/tests/metacall_load_configuration_fail_test/CMakeLists.txt @@ -110,11 +110,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_configuration_fail_test/source/main.cpp b/source/tests/metacall_load_configuration_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_configuration_fail_test/source/main.cpp +++ b/source/tests/metacall_load_configuration_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_configuration_fail_test/source/metacall_load_configuration_fail_test.cpp b/source/tests/metacall_load_configuration_fail_test/source/metacall_load_configuration_fail_test.cpp index 8632cb274c..0fe69549c7 100644 --- a/source/tests/metacall_load_configuration_fail_test/source/metacall_load_configuration_fail_test.cpp +++ b/source/tests/metacall_load_configuration_fail_test/source/metacall_load_configuration_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -72,5 +72,5 @@ TEST_F(metacall_load_configuration_fail_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_configuration_node_python_test/CMakeLists.txt b/source/tests/metacall_load_configuration_node_python_test/CMakeLists.txt index cb1dcf870f..6653f9010f 100644 --- a/source/tests/metacall_load_configuration_node_python_test/CMakeLists.txt +++ b/source/tests/metacall_load_configuration_node_python_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_configuration_node_python_test/source/main.cpp b/source/tests/metacall_load_configuration_node_python_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_configuration_node_python_test/source/main.cpp +++ b/source/tests/metacall_load_configuration_node_python_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_configuration_node_python_test/source/metacall_load_configuration_node_python_test.cpp b/source/tests/metacall_load_configuration_node_python_test/source/metacall_load_configuration_node_python_test.cpp index 92a253b9a8..09d50c5931 100644 --- a/source/tests/metacall_load_configuration_node_python_test/source/metacall_load_configuration_node_python_test.cpp +++ b/source/tests/metacall_load_configuration_node_python_test/source/metacall_load_configuration_node_python_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -55,5 +55,5 @@ TEST_F(metacall_load_configuration_node_python_test, DefaultConstructor) EXPECT_EQ((double)5.0, (double)metacall_value_to_double(ret)); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_configuration_python_node_test/CMakeLists.txt b/source/tests/metacall_load_configuration_python_node_test/CMakeLists.txt index 9191bf4f39..f8dd16c325 100644 --- a/source/tests/metacall_load_configuration_python_node_test/CMakeLists.txt +++ b/source/tests/metacall_load_configuration_python_node_test/CMakeLists.txt @@ -112,11 +112,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_configuration_python_node_test/source/main.cpp b/source/tests/metacall_load_configuration_python_node_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_configuration_python_node_test/source/main.cpp +++ b/source/tests/metacall_load_configuration_python_node_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_configuration_python_node_test/source/metacall_load_configuration_python_node_test.cpp b/source/tests/metacall_load_configuration_python_node_test/source/metacall_load_configuration_python_node_test.cpp index ae64810d4b..ece10c5b20 100644 --- a/source/tests/metacall_load_configuration_python_node_test/source/metacall_load_configuration_python_node_test.cpp +++ b/source/tests/metacall_load_configuration_python_node_test/source/metacall_load_configuration_python_node_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -62,5 +62,5 @@ TEST_F(metacall_load_configuration_python_node_test, DefaultConstructor) metacall_allocator_destroy(config_allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_configuration_relative_test/CMakeLists.txt b/source/tests/metacall_load_configuration_relative_test/CMakeLists.txt index efaabddc67..a16c0c46f7 100644 --- a/source/tests/metacall_load_configuration_relative_test/CMakeLists.txt +++ b/source/tests/metacall_load_configuration_relative_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_configuration_relative_test/include/metacall_load_configuration_relative_test/metacall_load_configuration_relative_test.h.in b/source/tests/metacall_load_configuration_relative_test/include/metacall_load_configuration_relative_test/metacall_load_configuration_relative_test.h.in index 8bfcd166dd..79701d0f7b 100644 --- a/source/tests/metacall_load_configuration_relative_test/include/metacall_load_configuration_relative_test/metacall_load_configuration_relative_test.h.in +++ b/source/tests/metacall_load_configuration_relative_test/include/metacall_load_configuration_relative_test/metacall_load_configuration_relative_test.h.in @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_configuration_relative_test/source/main.cpp b/source/tests/metacall_load_configuration_relative_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_configuration_relative_test/source/main.cpp +++ b/source/tests/metacall_load_configuration_relative_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_configuration_relative_test/source/metacall_load_configuration_relative_test.cpp b/source/tests/metacall_load_configuration_relative_test/source/metacall_load_configuration_relative_test.cpp index c14a1cedaa..be9556f5e1 100644 --- a/source/tests/metacall_load_configuration_relative_test/source/metacall_load_configuration_relative_test.cpp +++ b/source/tests/metacall_load_configuration_relative_test/source/metacall_load_configuration_relative_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -65,5 +65,5 @@ TEST_F(metacall_load_configuration_relative_test, DefaultConstructor) metacall_allocator_destroy(config_allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_configuration_test/CMakeLists.txt b/source/tests/metacall_load_configuration_test/CMakeLists.txt index a37dec7521..3c42adeb57 100644 --- a/source/tests/metacall_load_configuration_test/CMakeLists.txt +++ b/source/tests/metacall_load_configuration_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_configuration_test/source/main.cpp b/source/tests/metacall_load_configuration_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_configuration_test/source/main.cpp +++ b/source/tests/metacall_load_configuration_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 d3fc377c40..21657b9c8e 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -254,5 +254,5 @@ TEST_F(metacall_load_configuration_test, DefaultConstructor) metacall_allocator_destroy(config_allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_memory_empty_test/CMakeLists.txt b/source/tests/metacall_load_memory_empty_test/CMakeLists.txt index 0cb67b3d98..b98f18bca6 100644 --- a/source/tests/metacall_load_memory_empty_test/CMakeLists.txt +++ b/source/tests/metacall_load_memory_empty_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_memory_empty_test/source/main.cpp b/source/tests/metacall_load_memory_empty_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_memory_empty_test/source/main.cpp +++ b/source/tests/metacall_load_memory_empty_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_memory_empty_test/source/metacall_load_memory_empty_test.cpp b/source/tests/metacall_load_memory_empty_test/source/metacall_load_memory_empty_test.cpp index ee424fed8a..4adffb8e4a 100644 --- a/source/tests/metacall_load_memory_empty_test/source/metacall_load_memory_empty_test.cpp +++ b/source/tests/metacall_load_memory_empty_test/source/metacall_load_memory_empty_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -67,5 +67,5 @@ TEST_F(metacall_load_memory_empty_test, DefaultConstructor) /* Non existent loader */ ASSERT_EQ((int)1, (int)metacall_load_from_memory("asdfghjk", buffer, sizeof(buffer), NULL)); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_load_memory_test/CMakeLists.txt b/source/tests/metacall_load_memory_test/CMakeLists.txt index c85b9c10d9..9203a34ca2 100644 --- a/source/tests/metacall_load_memory_test/CMakeLists.txt +++ b/source/tests/metacall_load_memory_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_load_memory_test/source/main.cpp b/source/tests/metacall_load_memory_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_load_memory_test/source/main.cpp +++ b/source/tests/metacall_load_memory_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_load_memory_test/source/metacall_load_memory_test.cpp b/source/tests/metacall_load_memory_test/source/metacall_load_memory_test.cpp index b65eeb92e3..9610ddf73c 100644 --- a/source/tests/metacall_load_memory_test/source/metacall_load_memory_test.cpp +++ b/source/tests/metacall_load_memory_test/source/metacall_load_memory_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -157,5 +157,5 @@ TEST_F(metacall_load_memory_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_JS */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_logs_test/CMakeLists.txt b/source/tests/metacall_logs_test/CMakeLists.txt index 068c0cf217..2a56bf6371 100644 --- a/source/tests/metacall_logs_test/CMakeLists.txt +++ b/source/tests/metacall_logs_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_logs_test/source/main.cpp b/source/tests/metacall_logs_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_logs_test/source/main.cpp +++ b/source/tests/metacall_logs_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_logs_test/source/metacall_logs_test.cpp b/source/tests/metacall_logs_test/source/metacall_logs_test.cpp index 15c14c4cec..179554ab25 100644 --- a/source/tests/metacall_logs_test/source/metacall_logs_test.cpp +++ b/source/tests/metacall_logs_test/source/metacall_logs_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -40,5 +40,5 @@ TEST_F(metacall_logs_test, DefaultConstructor) ASSERT_EQ((int)0, (int)metacall_initialize()); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_lua_test/CMakeLists.txt b/source/tests/metacall_lua_test/CMakeLists.txt index d8d2cfc014..d356553b5c 100644 --- a/source/tests/metacall_lua_test/CMakeLists.txt +++ b/source/tests/metacall_lua_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_lua_test/source/main.cpp b/source/tests/metacall_lua_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_lua_test/source/main.cpp +++ b/source/tests/metacall_lua_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_lua_test/source/metacall_lua_test.cpp b/source/tests/metacall_lua_test/source/metacall_lua_test.cpp index e229265f78..63c84b4375 100644 --- a/source/tests/metacall_lua_test/source/metacall_lua_test.cpp +++ b/source/tests/metacall_lua_test/source/metacall_lua_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -110,5 +110,5 @@ TEST_F(metacall_lua_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_map_await_test/CMakeLists.txt b/source/tests/metacall_map_await_test/CMakeLists.txt index c70decf95e..6b1df3e956 100644 --- a/source/tests/metacall_map_await_test/CMakeLists.txt +++ b/source/tests/metacall_map_await_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_map_await_test/source/main.cpp b/source/tests/metacall_map_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_map_await_test/source/main.cpp +++ b/source/tests/metacall_map_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 8c3646f924..d3f1d4eb76 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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; @@ -263,7 +263,7 @@ TEST_F(metacall_map_await_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); /* NodeJS */ #if defined(OPTION_BUILD_LOADERS_NODE) diff --git a/source/tests/metacall_map_test/CMakeLists.txt b/source/tests/metacall_map_test/CMakeLists.txt index 72cbbcab03..b9d40bf14a 100644 --- a/source/tests/metacall_map_test/CMakeLists.txt +++ b/source/tests/metacall_map_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_map_test/source/main.cpp b/source/tests/metacall_map_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_map_test/source/main.cpp +++ b/source/tests/metacall_map_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 ceb829c788..84d641f4d0 100644 --- a/source/tests/metacall_map_test/source/metacall_map_test.cpp +++ b/source/tests/metacall_map_test/source/metacall_map_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); */ @@ -210,5 +210,5 @@ TEST_F(metacall_map_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_async_multiple_test/CMakeLists.txt b/source/tests/metacall_node_async_multiple_test/CMakeLists.txt index 7fc6365c90..77c1e4b31e 100644 --- a/source/tests/metacall_node_async_multiple_test/CMakeLists.txt +++ b/source/tests/metacall_node_async_multiple_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_async_multiple_test/source/main.cpp b/source/tests/metacall_node_async_multiple_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_async_multiple_test/source/main.cpp +++ b/source/tests/metacall_node_async_multiple_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_async_multiple_test/source/metacall_node_async_multiple_test.cpp b/source/tests/metacall_node_async_multiple_test/source/metacall_node_async_multiple_test.cpp index 629b1c7890..157a31a02c 100644 --- a/source/tests/metacall_node_async_multiple_test/source/metacall_node_async_multiple_test.cpp +++ b/source/tests/metacall_node_async_multiple_test/source/metacall_node_async_multiple_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -198,7 +198,7 @@ TEST_F(metacall_node_async_multiple_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); /* NodeJS */ #if defined(OPTION_BUILD_LOADERS_NODE) diff --git a/source/tests/metacall_node_async_resources_test/CMakeLists.txt b/source/tests/metacall_node_async_resources_test/CMakeLists.txt index f57aeb3776..17e130e414 100644 --- a/source/tests/metacall_node_async_resources_test/CMakeLists.txt +++ b/source/tests/metacall_node_async_resources_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_async_resources_test/source/main.cpp b/source/tests/metacall_node_async_resources_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_async_resources_test/source/main.cpp +++ b/source/tests/metacall_node_async_resources_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_async_resources_test/source/metacall_node_async_resources_test.cpp b/source/tests/metacall_node_async_resources_test/source/metacall_node_async_resources_test.cpp index 4a979174ed..82d2178970 100644 --- a/source/tests/metacall_node_async_resources_test/source/metacall_node_async_resources_test.cpp +++ b/source/tests/metacall_node_async_resources_test/source/metacall_node_async_resources_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -46,5 +46,5 @@ TEST_F(metacall_node_event_loop_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_async_test/CMakeLists.txt b/source/tests/metacall_node_async_test/CMakeLists.txt index 43e43eb6a7..d58db66234 100644 --- a/source/tests/metacall_node_async_test/CMakeLists.txt +++ b/source/tests/metacall_node_async_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_async_test/source/main.cpp b/source/tests/metacall_node_async_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_async_test/source/main.cpp +++ b/source/tests/metacall_node_async_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_async_test/source/metacall_node_async_test.cpp b/source/tests/metacall_node_async_test/source/metacall_node_async_test.cpp index 8c125563f1..e7a8395355 100644 --- a/source/tests/metacall_node_async_test/source/metacall_node_async_test.cpp +++ b/source/tests/metacall_node_async_test/source/metacall_node_async_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -252,7 +252,7 @@ TEST_F(metacall_node_async_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); /* NodeJS */ #if defined(OPTION_BUILD_LOADERS_NODE) diff --git a/source/tests/metacall_node_await_chain_test/CMakeLists.txt b/source/tests/metacall_node_await_chain_test/CMakeLists.txt index 8fc2574d98..52e4ab39e3 100644 --- a/source/tests/metacall_node_await_chain_test/CMakeLists.txt +++ b/source/tests/metacall_node_await_chain_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_await_chain_test/source/main.cpp b/source/tests/metacall_node_await_chain_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_await_chain_test/source/main.cpp +++ b/source/tests/metacall_node_await_chain_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_await_chain_test/source/metacall_node_await_chain_test.cpp b/source/tests/metacall_node_await_chain_test/source/metacall_node_await_chain_test.cpp index 308dff2bf3..1efdd46827 100644 --- a/source/tests/metacall_node_await_chain_test/source/metacall_node_await_chain_test.cpp +++ b/source/tests/metacall_node_await_chain_test/source/metacall_node_await_chain_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -95,7 +95,7 @@ TEST_F(metacall_node_await_chain_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); EXPECT_EQ((unsigned int)3, (unsigned int)callbacks_executed); } diff --git a/source/tests/metacall_node_call_test/CMakeLists.txt b/source/tests/metacall_node_call_test/CMakeLists.txt index 1c86441a0f..c0a877d4df 100644 --- a/source/tests/metacall_node_call_test/CMakeLists.txt +++ b/source/tests/metacall_node_call_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_call_test/source/main.cpp b/source/tests/metacall_node_call_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_call_test/source/main.cpp +++ b/source/tests/metacall_node_call_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_call_test/source/metacall_node_call_test.cpp b/source/tests/metacall_node_call_test/source/metacall_node_call_test.cpp index 7d1fbd59af..7117e09419 100644 --- a/source/tests/metacall_node_call_test/source/metacall_node_call_test.cpp +++ b/source/tests/metacall_node_call_test/source/metacall_node_call_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -67,5 +67,5 @@ TEST_F(metacall_node_call_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_callback_test/CMakeLists.txt b/source/tests/metacall_node_callback_test/CMakeLists.txt index 6c50252a10..1ba50b6375 100644 --- a/source/tests/metacall_node_callback_test/CMakeLists.txt +++ b/source/tests/metacall_node_callback_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_callback_test/source/main.cpp b/source/tests/metacall_node_callback_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_callback_test/source/main.cpp +++ b/source/tests/metacall_node_callback_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_callback_test/source/metacall_node_callback_test.cpp b/source/tests/metacall_node_callback_test/source/metacall_node_callback_test.cpp index a8a4bd900b..a49f61313b 100644 --- a/source/tests/metacall_node_callback_test/source/metacall_node_callback_test.cpp +++ b/source/tests/metacall_node_callback_test/source/metacall_node_callback_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -66,5 +66,5 @@ TEST_F(metacall_node_callback_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_clear_mem_test/CMakeLists.txt b/source/tests/metacall_node_clear_mem_test/CMakeLists.txt index 511ce96e65..d7f9e9124c 100644 --- a/source/tests/metacall_node_clear_mem_test/CMakeLists.txt +++ b/source/tests/metacall_node_clear_mem_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_clear_mem_test/source/main.cpp b/source/tests/metacall_node_clear_mem_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_clear_mem_test/source/main.cpp +++ b/source/tests/metacall_node_clear_mem_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_clear_mem_test/source/metacall_node_clear_mem_test.cpp b/source/tests/metacall_node_clear_mem_test/source/metacall_node_clear_mem_test.cpp index 17e38ea18e..ae63885773 100644 --- a/source/tests/metacall_node_clear_mem_test/source/metacall_node_clear_mem_test.cpp +++ b/source/tests/metacall_node_clear_mem_test/source/metacall_node_clear_mem_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -64,5 +64,5 @@ TEST_F(metacall_node_clear_mem_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_default_export_test/CMakeLists.txt b/source/tests/metacall_node_default_export_test/CMakeLists.txt index 4e1f5477b8..c009589339 100644 --- a/source/tests/metacall_node_default_export_test/CMakeLists.txt +++ b/source/tests/metacall_node_default_export_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_default_export_test/source/main.cpp b/source/tests/metacall_node_default_export_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_default_export_test/source/main.cpp +++ b/source/tests/metacall_node_default_export_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_default_export_test/source/metacall_node_default_export_test.cpp b/source/tests/metacall_node_default_export_test/source/metacall_node_default_export_test.cpp index 6e51c13c10..890c8b8726 100644 --- a/source/tests/metacall_node_default_export_test/source/metacall_node_default_export_test.cpp +++ b/source/tests/metacall_node_default_export_test/source/metacall_node_default_export_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -83,5 +83,5 @@ TEST_F(metacall_node_default_export_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_event_loop_signal_test/CMakeLists.txt b/source/tests/metacall_node_event_loop_signal_test/CMakeLists.txt index b47b5650d6..cb3e4701ce 100644 --- a/source/tests/metacall_node_event_loop_signal_test/CMakeLists.txt +++ b/source/tests/metacall_node_event_loop_signal_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_event_loop_signal_test/source/main.cpp b/source/tests/metacall_node_event_loop_signal_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_event_loop_signal_test/source/main.cpp +++ b/source/tests/metacall_node_event_loop_signal_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_event_loop_signal_test/source/metacall_node_event_loop_signal_test.cpp b/source/tests/metacall_node_event_loop_signal_test/source/metacall_node_event_loop_signal_test.cpp index 5cf2feeb3b..54d7cb8fa2 100644 --- a/source/tests/metacall_node_event_loop_signal_test/source/metacall_node_event_loop_signal_test.cpp +++ b/source/tests/metacall_node_event_loop_signal_test/source/metacall_node_event_loop_signal_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -54,5 +54,5 @@ TEST_F(metacall_node_event_loop_signal_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_event_loop_test/CMakeLists.txt b/source/tests/metacall_node_event_loop_test/CMakeLists.txt index ddbf38c2cf..d1d83d4416 100644 --- a/source/tests/metacall_node_event_loop_test/CMakeLists.txt +++ b/source/tests/metacall_node_event_loop_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_event_loop_test/source/main.cpp b/source/tests/metacall_node_event_loop_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_event_loop_test/source/main.cpp +++ b/source/tests/metacall_node_event_loop_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_event_loop_test/source/metacall_node_event_loop_test.cpp b/source/tests/metacall_node_event_loop_test/source/metacall_node_event_loop_test.cpp index 350386b0cc..306cda37b0 100644 --- a/source/tests/metacall_node_event_loop_test/source/metacall_node_event_loop_test.cpp +++ b/source/tests/metacall_node_event_loop_test/source/metacall_node_event_loop_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -46,5 +46,5 @@ TEST_F(metacall_node_event_loop_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_exception_test/CMakeLists.txt b/source/tests/metacall_node_exception_test/CMakeLists.txt index f203c824c3..1129b31459 100644 --- a/source/tests/metacall_node_exception_test/CMakeLists.txt +++ b/source/tests/metacall_node_exception_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_exception_test/source/main.cpp b/source/tests/metacall_node_exception_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_exception_test/source/main.cpp +++ b/source/tests/metacall_node_exception_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 a82a9ed6cc..fd1c3b2e26 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -75,5 +75,5 @@ TEST_F(metacall_node_exception_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_extension_test/CMakeLists.txt b/source/tests/metacall_node_extension_test/CMakeLists.txt index 33c372ae83..f56da937ab 100644 --- a/source/tests/metacall_node_extension_test/CMakeLists.txt +++ b/source/tests/metacall_node_extension_test/CMakeLists.txt @@ -110,11 +110,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_extension_test/node_extension_test/CMakeLists.txt b/source/tests/metacall_node_extension_test/node_extension_test/CMakeLists.txt index 997208d44f..1efbefcc03 100644 --- a/source/tests/metacall_node_extension_test/node_extension_test/CMakeLists.txt +++ b/source/tests/metacall_node_extension_test/node_extension_test/CMakeLists.txt @@ -177,7 +177,6 @@ target_link_options(${target} PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/IGNORE:4199> $<$<CXX_COMPILER_ID:MSVC>:/DELAYLOAD:${NodeJS_LIBRARY_NAME}> - $<$<CXX_COMPILER_ID:MSVC>:/DELAYLOAD:${NodeJS_LIBRARY_NAME}> $<$<AND:$<BOOL:${APPLE}>,$<CXX_COMPILER_ID:AppleClang,Clang>>:-undefined dynamic_lookup> PUBLIC diff --git a/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test.c b/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test.c index a9b08fed4c..a0df94beac 100644 --- a/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test.c +++ b/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test.c @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test_win32_delay_load.cpp b/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test_win32_delay_load.cpp index 8ab28a9acc..fc968f846a 100644 --- a/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test_win32_delay_load.cpp +++ b/source/tests/metacall_node_extension_test/node_extension_test/source/node_extension_test_win32_delay_load.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -29,6 +29,8 @@ #include <delayimp.h> #include <string.h> +static const char node_library_name[] = NODEJS_LIBRARY_NAME; + static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo *info) { HMODULE m; @@ -38,7 +40,7 @@ static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo *info) return NULL; } - if (_stricmp(info->szDll, NODEJS_LIBRARY_NAME) != 0) + if (_stricmp(info->szDll, node_library_name) != 0) { return NULL; } diff --git a/source/tests/metacall_node_extension_test/source/main.cpp b/source/tests/metacall_node_extension_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_extension_test/source/main.cpp +++ b/source/tests/metacall_node_extension_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 f091bf53c5..ef5fd6caf7 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -79,5 +79,5 @@ TEST_F(metacall_node_extension_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_fail_env_var_test/CMakeLists.txt b/source/tests/metacall_node_fail_env_var_test/CMakeLists.txt index 0e629197c8..ecd42051ef 100644 --- a/source/tests/metacall_node_fail_env_var_test/CMakeLists.txt +++ b/source/tests/metacall_node_fail_env_var_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_fail_env_var_test/source/main.cpp b/source/tests/metacall_node_fail_env_var_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_fail_env_var_test/source/main.cpp +++ b/source/tests/metacall_node_fail_env_var_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_fail_env_var_test/source/metacall_node_fail_env_var_test.cpp b/source/tests/metacall_node_fail_env_var_test/source/metacall_node_fail_env_var_test.cpp index 6c3e0f255d..b6ef3dc8a2 100644 --- a/source/tests/metacall_node_fail_env_var_test/source/metacall_node_fail_env_var_test.cpp +++ b/source/tests/metacall_node_fail_env_var_test/source/metacall_node_fail_env_var_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -66,5 +66,5 @@ TEST_F(metacall_node_fail_env_var_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_fail_load_leak_test/CMakeLists.txt b/source/tests/metacall_node_fail_load_leak_test/CMakeLists.txt index 35d46706ac..3b1cc5bc5e 100644 --- a/source/tests/metacall_node_fail_load_leak_test/CMakeLists.txt +++ b/source/tests/metacall_node_fail_load_leak_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_fail_load_leak_test/source/main.cpp b/source/tests/metacall_node_fail_load_leak_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_fail_load_leak_test/source/main.cpp +++ b/source/tests/metacall_node_fail_load_leak_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_fail_load_leak_test/source/metacall_node_fail_load_leak_test.cpp b/source/tests/metacall_node_fail_load_leak_test/source/metacall_node_fail_load_leak_test.cpp index a9c44e1f68..a47ec3c226 100644 --- a/source/tests/metacall_node_fail_load_leak_test/source/metacall_node_fail_load_leak_test.cpp +++ b/source/tests/metacall_node_fail_load_leak_test/source/metacall_node_fail_load_leak_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -70,5 +70,5 @@ TEST_F(metacall_node_fail_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_fail_test/CMakeLists.txt b/source/tests/metacall_node_fail_test/CMakeLists.txt index cdb112b965..2f46c9261f 100644 --- a/source/tests/metacall_node_fail_test/CMakeLists.txt +++ b/source/tests/metacall_node_fail_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_fail_test/source/main.cpp b/source/tests/metacall_node_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_fail_test/source/main.cpp +++ b/source/tests/metacall_node_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_fail_test/source/metacall_node_fail_test.cpp b/source/tests/metacall_node_fail_test/source/metacall_node_fail_test.cpp index d065434d00..e052ed25b2 100644 --- a/source/tests/metacall_node_fail_test/source/metacall_node_fail_test.cpp +++ b/source/tests/metacall_node_fail_test/source/metacall_node_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -71,5 +71,5 @@ TEST_F(metacall_node_fail_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_inline_test/CMakeLists.txt b/source/tests/metacall_node_inline_test/CMakeLists.txt index 8d86c00caa..8f7c771f26 100644 --- a/source/tests/metacall_node_inline_test/CMakeLists.txt +++ b/source/tests/metacall_node_inline_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_inline_test/source/main.cpp b/source/tests/metacall_node_inline_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_inline_test/source/main.cpp +++ b/source/tests/metacall_node_inline_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_inline_test/source/metacall_node_inline_test.cpp b/source/tests/metacall_node_inline_test/source/metacall_node_inline_test.cpp index c8f9f767c8..1c578f6eab 100644 --- a/source/tests/metacall_node_inline_test/source/metacall_node_inline_test.cpp +++ b/source/tests/metacall_node_inline_test/source/metacall_node_inline_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -81,5 +81,5 @@ TEST_F(metacall_node_inline_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_multithread_deadlock_test/CMakeLists.txt b/source/tests/metacall_node_multithread_deadlock_test/CMakeLists.txt index 3140153022..e09b978263 100644 --- a/source/tests/metacall_node_multithread_deadlock_test/CMakeLists.txt +++ b/source/tests/metacall_node_multithread_deadlock_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_multithread_deadlock_test/source/main.cpp b/source/tests/metacall_node_multithread_deadlock_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_multithread_deadlock_test/source/main.cpp +++ b/source/tests/metacall_node_multithread_deadlock_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_multithread_deadlock_test/source/metacall_node_multithread_deadlock_test.cpp b/source/tests/metacall_node_multithread_deadlock_test/source/metacall_node_multithread_deadlock_test.cpp index d1b33518e3..39ff07dabe 100644 --- a/source/tests/metacall_node_multithread_deadlock_test/source/metacall_node_multithread_deadlock_test.cpp +++ b/source/tests/metacall_node_multithread_deadlock_test/source/metacall_node_multithread_deadlock_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -125,7 +125,7 @@ TEST_F(metacall_node_multithread_deadlock_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); /* NodeJS */ #if defined(OPTION_BUILD_LOADERS_NODE) diff --git a/source/tests/metacall_node_native_code_test/CMakeLists.txt b/source/tests/metacall_node_native_code_test/CMakeLists.txt index e915ed3b77..2f485938eb 100644 --- a/source/tests/metacall_node_native_code_test/CMakeLists.txt +++ b/source/tests/metacall_node_native_code_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_native_code_test/source/main.cpp b/source/tests/metacall_node_native_code_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_native_code_test/source/main.cpp +++ b/source/tests/metacall_node_native_code_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_native_code_test/source/metacall_node_native_code_test.cpp b/source/tests/metacall_node_native_code_test/source/metacall_node_native_code_test.cpp index 83bd3466be..4366808cc2 100644 --- a/source/tests/metacall_node_native_code_test/source/metacall_node_native_code_test.cpp +++ b/source/tests/metacall_node_native_code_test/source/metacall_node_native_code_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -68,5 +68,5 @@ TEST_F(metacall_node_unsupported_features_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_port_await_test/CMakeLists.txt b/source/tests/metacall_node_port_await_test/CMakeLists.txt index 7afce5c27e..819a878a01 100644 --- a/source/tests/metacall_node_port_await_test/CMakeLists.txt +++ b/source/tests/metacall_node_port_await_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_port_await_test/source/main.cpp b/source/tests/metacall_node_port_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_port_await_test/source/main.cpp +++ b/source/tests/metacall_node_port_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_port_await_test/source/metacall_node_port_await_test.cpp b/source/tests/metacall_node_port_await_test/source/metacall_node_port_await_test.cpp index 34d49f16ee..43cb8e8db0 100644 --- a/source/tests/metacall_node_port_await_test/source/metacall_node_port_await_test.cpp +++ b/source/tests/metacall_node_port_await_test/source/metacall_node_port_await_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -71,5 +71,5 @@ TEST_F(metacall_node_port_await_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_port_c_lib_test/CMakeLists.txt b/source/tests/metacall_node_port_c_lib_test/CMakeLists.txt new file mode 100644 index 0000000000..ab55d51e7d --- /dev/null +++ b/source/tests/metacall_node_port_c_lib_test/CMakeLists.txt @@ -0,0 +1,176 @@ +# Check if this loader is enabled +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_LOADERS_C OR NOT OPTION_BUILD_PORTS OR NOT OPTION_BUILD_PORTS_NODE) + return() +endif() + +# +# External dependencies +# + +find_package(LibGit2) + +if(NOT LibGit2_FOUND) + message(WARNING "LibGit2 libraries not found, skipping test metacall-node-port-c-lib-test") + return() +endif() + +# +# Executable name and options +# + +# Target name +set(target metacall-node-port-c-lib-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_node_port_c_lib_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}::metacall +) + +# +# Compile definitions +# + +target_compile_definitions(${target} + PRIVATE + ${DEFAULT_COMPILE_DEFINITIONS} + + # NodeJS Port path + METACALL_NODE_PORT_PATH="${CMAKE_SOURCE_DIR}/source/ports/node_port/index.js" + + # LibGit2 paths + LIBGIT2_LIBRARY_DIR="${LibGit2_LIBRARY_DIR}" + LIBGIT2_INCLUDE_DIR="${LibGit2_INCLUDE_DIR}" +) + +# +# 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} + node_port + node_loader + c_loader +) + +# +# 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_node_port_c_lib_test/source/main.cpp b/source/tests/metacall_node_port_c_lib_test/source/main.cpp new file mode 100644 index 0000000000..5820341294 --- /dev/null +++ b/source/tests/metacall_node_port_c_lib_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_node_port_c_lib_test/source/metacall_node_port_c_lib_test.cpp b/source/tests/metacall_node_port_c_lib_test/source/metacall_node_port_c_lib_test.cpp new file mode 100644 index 0000000000..7070bbf985 --- /dev/null +++ b/source/tests/metacall_node_port_c_lib_test/source/metacall_node_port_c_lib_test.cpp @@ -0,0 +1,57 @@ +/* + * 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> +#include <metacall/metacall_value.h> + +class metacall_node_port_c_lib_test : public testing::Test +{ +public: +}; + +TEST_F(metacall_node_port_c_lib_test, DefaultConstructor) +{ + metacall_print_info(); + + ASSERT_EQ((int)0, (int)metacall_initialize()); + + static const char buffer[] = + /* NodeJS */ + "const assert = require('assert');\n" + "const { metacall_execution_path, metacall_load_from_package_export } = require('" METACALL_NODE_PORT_PATH "');\n" + /* C Lib Paths */ + "metacall_execution_path('c', '" LIBGIT2_INCLUDE_DIR "');\n" + "metacall_execution_path('c', '" LIBGIT2_LIBRARY_DIR "');\n" + /* C Lib Require */ + "const git2 = metacall_load_from_package_export('c', 'git2');\n" + "const { git_libgit2_init, git_libgit2_shutdown } = git2;\n" + "console.log(git2);\n" + /* C Lib Assert */ + "assert(git_libgit2_init() >= 0, 'libgit2 initialization failed');\n" + "git_libgit2_shutdown();\n" + "\n"; + + ASSERT_EQ((int)0, (int)metacall_load_from_memory("node", buffer, sizeof(buffer), NULL)); + + metacall_destroy(); +} diff --git a/source/tests/metacall_node_port_rs_test/CMakeLists.txt b/source/tests/metacall_node_port_rs_test/CMakeLists.txt index 2882f86306..57422785bd 100644 --- a/source/tests/metacall_node_port_rs_test/CMakeLists.txt +++ b/source/tests/metacall_node_port_rs_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_port_rs_test/source/main.cpp b/source/tests/metacall_node_port_rs_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_port_rs_test/source/main.cpp +++ b/source/tests/metacall_node_port_rs_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_port_rs_test/source/metacall_node_port_rs_test.cpp b/source/tests/metacall_node_port_rs_test/source/metacall_node_port_rs_test.cpp index 3c34a8094d..dc54f4d0c9 100644 --- a/source/tests/metacall_node_port_rs_test/source/metacall_node_port_rs_test.cpp +++ b/source/tests/metacall_node_port_rs_test/source/metacall_node_port_rs_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -55,5 +55,5 @@ TEST_F(metacall_node_port_rs_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_RS */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_port_test/CMakeLists.txt b/source/tests/metacall_node_port_test/CMakeLists.txt index 6ffc2981bf..5568059519 100644 --- a/source/tests/metacall_node_port_test/CMakeLists.txt +++ b/source/tests/metacall_node_port_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -193,15 +202,15 @@ add_dependencies(${target} set(NodeJS_EXECUTABLE_ONLY ON) find_package(NodeJS) -find_package(Python COMPONENTS Interpreter) +find_package(Python3 COMPONENTS Interpreter) -if(NodeJS_FOUND AND Python_Interpreter_FOUND) +if(NodeJS_FOUND AND Python3_Interpreter_FOUND) execute_process( COMMAND ${NodeJS_EXECUTABLE} -e "console.log(process.versions.openssl)" OUTPUT_VARIABLE NODEJS_OPENSSL_VERSION ) execute_process( - COMMAND ${Python_EXECUTABLE} -c "import ssl; print(ssl.OPENSSL_VERSION.split()[1])" + COMMAND ${Python3_EXECUTABLE} -c "import ssl; print(ssl.OPENSSL_VERSION.split()[1])" OUTPUT_VARIABLE PYTHON_OPENSSL_VERSION ) @@ -231,4 +240,5 @@ test_environment_variables(${target} ${TESTS_ENVIRONMENT_VARIABLES_C} ${TESTS_ENVIRONMENT_VARIABLES_RS} ${TESTS_ENVIRONMENT_VARIABLES_OPENSSL} + "NODE_PORT_TEST_EXPORTS=1" ) diff --git a/source/tests/metacall_node_port_test/source/main.cpp b/source/tests/metacall_node_port_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_port_test/source/main.cpp +++ b/source/tests/metacall_node_port_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 3b3552186b..ab1d6df112 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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; }; @@ -75,15 +75,15 @@ TEST_F(metacall_node_port_test, DefaultConstructor) void *future = metacall_await("main", metacall_null_args, accept, reject, static_cast<void *>(&await_data)); - await_data.c.wait(lock); + ASSERT_NE((void *)NULL, (void *)future); - EXPECT_NE((void *)NULL, (void *)future); + ASSERT_EQ((enum metacall_value_id)metacall_value_id(future), (enum metacall_value_id)METACALL_FUTURE); - EXPECT_EQ((enum metacall_value_id)metacall_value_id(future), (enum metacall_value_id)METACALL_FUTURE); + await_data.c.wait(lock); metacall_value_destroy(future); } #endif /* OPTION_BUILD_LOADERS_NODE */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_async_after_destroy_test/CMakeLists.txt b/source/tests/metacall_node_python_async_after_destroy_test/CMakeLists.txt index f08873f6e0..6c88f28d6b 100644 --- a/source/tests/metacall_node_python_async_after_destroy_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_async_after_destroy_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_async_after_destroy_test/source/main.cpp b/source/tests/metacall_node_python_async_after_destroy_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_async_after_destroy_test/source/main.cpp +++ b/source/tests/metacall_node_python_async_after_destroy_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_async_after_destroy_test/source/metacall_node_python_async_after_destroy_test.cpp b/source/tests/metacall_node_python_async_after_destroy_test/source/metacall_node_python_async_after_destroy_test.cpp index 464e9b7503..71ebbcdeab 100644 --- a/source/tests/metacall_node_python_async_after_destroy_test/source/metacall_node_python_async_after_destroy_test.cpp +++ b/source/tests/metacall_node_python_async_after_destroy_test/source/metacall_node_python_async_after_destroy_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -65,5 +65,5 @@ TEST_F(metacall_node_python_async_after_destroy_test, DefaultConstructor) * https://github.com/metacall/core/commit/9b64ee533079fa0d543fc346fb7149d1086451f0 * https://github.com/metacall/core/commit/22bd999c281f23aac04cea7df435a836631706da */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_await_extended_test/CMakeLists.txt b/source/tests/metacall_node_python_await_extended_test/CMakeLists.txt index af1945174b..a82165e896 100644 --- a/source/tests/metacall_node_python_await_extended_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_await_extended_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_await_extended_test/source/main.cpp b/source/tests/metacall_node_python_await_extended_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_await_extended_test/source/main.cpp +++ b/source/tests/metacall_node_python_await_extended_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_await_extended_test/source/metacall_node_python_await_extended_test.cpp b/source/tests/metacall_node_python_await_extended_test/source/metacall_node_python_await_extended_test.cpp index ef20b69f40..d773f0ba76 100644 --- a/source/tests/metacall_node_python_await_extended_test/source/metacall_node_python_await_extended_test.cpp +++ b/source/tests/metacall_node_python_await_extended_test/source/metacall_node_python_await_extended_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -90,5 +90,5 @@ TEST_F(metacall_node_python_await_extended_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_await_test/CMakeLists.txt b/source/tests/metacall_node_python_await_test/CMakeLists.txt index 70da8a5441..3553dbc2ca 100644 --- a/source/tests/metacall_node_python_await_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_await_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_await_test/source/main.cpp b/source/tests/metacall_node_python_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_await_test/source/main.cpp +++ b/source/tests/metacall_node_python_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_await_test/source/metacall_node_python_await_test.cpp b/source/tests/metacall_node_python_await_test/source/metacall_node_python_await_test.cpp index 2f7160c5dd..9e63b1aa3c 100644 --- a/source/tests/metacall_node_python_await_test/source/metacall_node_python_await_test.cpp +++ b/source/tests/metacall_node_python_await_test/source/metacall_node_python_await_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -84,5 +84,5 @@ TEST_F(metacall_node_python_await_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_deadlock_test/CMakeLists.txt b/source/tests/metacall_node_python_deadlock_test/CMakeLists.txt index 4f2cd49f91..55bcbfed39 100644 --- a/source/tests/metacall_node_python_deadlock_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_deadlock_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_deadlock_test/source/main.cpp b/source/tests/metacall_node_python_deadlock_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_deadlock_test/source/main.cpp +++ b/source/tests/metacall_node_python_deadlock_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_deadlock_test/source/metacall_node_python_deadlock_test.cpp b/source/tests/metacall_node_python_deadlock_test/source/metacall_node_python_deadlock_test.cpp index 95c5f2d9b3..d5cca59f22 100644 --- a/source/tests/metacall_node_python_deadlock_test/source/metacall_node_python_deadlock_test.cpp +++ b/source/tests/metacall_node_python_deadlock_test/source/metacall_node_python_deadlock_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -54,5 +54,5 @@ TEST_F(metacall_node_python_deadlock_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_exception_test/CMakeLists.txt b/source/tests/metacall_node_python_exception_test/CMakeLists.txt index af4c39982f..0d4b368692 100644 --- a/source/tests/metacall_node_python_exception_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_exception_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_exception_test/source/main.cpp b/source/tests/metacall_node_python_exception_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_exception_test/source/main.cpp +++ b/source/tests/metacall_node_python_exception_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_exception_test/source/metacall_node_python_exception_test.cpp b/source/tests/metacall_node_python_exception_test/source/metacall_node_python_exception_test.cpp index abe3e4a495..73f59386c1 100644 --- a/source/tests/metacall_node_python_exception_test/source/metacall_node_python_exception_test.cpp +++ b/source/tests/metacall_node_python_exception_test/source/metacall_node_python_exception_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -59,5 +59,5 @@ TEST_F(metacall_node_python_exception_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_port_mock_test/CMakeLists.txt b/source/tests/metacall_node_python_port_mock_test/CMakeLists.txt index 2179b2e2be..cbe593374d 100644 --- a/source/tests/metacall_node_python_port_mock_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_port_mock_test/CMakeLists.txt @@ -112,11 +112,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_port_mock_test/source/main.cpp b/source/tests/metacall_node_python_port_mock_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_port_mock_test/source/main.cpp +++ b/source/tests/metacall_node_python_port_mock_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_port_mock_test/source/metacall_node_python_port_mock_test.cpp b/source/tests/metacall_node_python_port_mock_test/source/metacall_node_python_port_mock_test.cpp index c1db00da3e..b1c9b76b4c 100644 --- a/source/tests/metacall_node_python_port_mock_test/source/metacall_node_python_port_mock_test.cpp +++ b/source/tests/metacall_node_python_port_mock_test/source/metacall_node_python_port_mock_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -64,5 +64,5 @@ TEST_F(metacall_node_python_port_mock_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY && OPTION_BUILD_LOADERS_MOCK */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_port_ruby_test/CMakeLists.txt b/source/tests/metacall_node_python_port_ruby_test/CMakeLists.txt index d6299a6ae5..6dfbd6c337 100644 --- a/source/tests/metacall_node_python_port_ruby_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_port_ruby_test/CMakeLists.txt @@ -112,11 +112,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_port_ruby_test/source/main.cpp b/source/tests/metacall_node_python_port_ruby_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_port_ruby_test/source/main.cpp +++ b/source/tests/metacall_node_python_port_ruby_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_port_ruby_test/source/metacall_node_python_port_ruby_test.cpp b/source/tests/metacall_node_python_port_ruby_test/source/metacall_node_python_port_ruby_test.cpp index 87ce31cb02..19acb40e98 100644 --- a/source/tests/metacall_node_python_port_ruby_test/source/metacall_node_python_port_ruby_test.cpp +++ b/source/tests/metacall_node_python_port_ruby_test/source/metacall_node_python_port_ruby_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -59,5 +59,5 @@ TEST_F(metacall_node_python_port_ruby_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY && OPTION_BUILD_LOADERS_RB */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_python_ruby_test/CMakeLists.txt b/source/tests/metacall_node_python_ruby_test/CMakeLists.txt index 20f09c16a7..b5e2914333 100644 --- a/source/tests/metacall_node_python_ruby_test/CMakeLists.txt +++ b/source/tests/metacall_node_python_ruby_test/CMakeLists.txt @@ -118,11 +118,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_python_ruby_test/source/main.cpp b/source/tests/metacall_node_python_ruby_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_python_ruby_test/source/main.cpp +++ b/source/tests/metacall_node_python_ruby_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_python_ruby_test/source/metacall_node_python_ruby_test.cpp b/source/tests/metacall_node_python_ruby_test/source/metacall_node_python_ruby_test.cpp index 246e93b8ac..6253dffc4c 100644 --- a/source/tests/metacall_node_python_ruby_test/source/metacall_node_python_ruby_test.cpp +++ b/source/tests/metacall_node_python_ruby_test/source/metacall_node_python_ruby_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -86,7 +86,7 @@ TEST_F(metacall_node_python_ruby_test, DefaultConstructor) "module.exports = {\n" " test: async function () {\n" " try {\n" - " const result = fetch('http://github.com/service/https://www.google.com/');\n" + " const result = fetch('http://github.com/service/https://www.google.com/', { signal: AbortSignal.timeout(60000) });\n" " console.log(result);\n" " return true;\n" " } catch (e) {\n" @@ -110,5 +110,5 @@ TEST_F(metacall_node_python_ruby_test, DefaultConstructor) EXPECT_EQ((int)success_callbacks, (int)1); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_reentrant_test/CMakeLists.txt b/source/tests/metacall_node_reentrant_test/CMakeLists.txt index 02e4976818..6dfff474f4 100644 --- a/source/tests/metacall_node_reentrant_test/CMakeLists.txt +++ b/source/tests/metacall_node_reentrant_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_reentrant_test/source/main.cpp b/source/tests/metacall_node_reentrant_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_reentrant_test/source/main.cpp +++ b/source/tests/metacall_node_reentrant_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_reentrant_test/source/metacall_node_reentrant_test.cpp b/source/tests/metacall_node_reentrant_test/source/metacall_node_reentrant_test.cpp index 2f32965ecd..09f0c7af6c 100644 --- a/source/tests/metacall_node_reentrant_test/source/metacall_node_reentrant_test.cpp +++ b/source/tests/metacall_node_reentrant_test/source/metacall_node_reentrant_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -119,5 +119,5 @@ TEST_F(metacall_node_reentrant_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_signal_handler_test/CMakeLists.txt b/source/tests/metacall_node_signal_handler_test/CMakeLists.txt index 29cc2a68c8..473ad45e51 100644 --- a/source/tests/metacall_node_signal_handler_test/CMakeLists.txt +++ b/source/tests/metacall_node_signal_handler_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_signal_handler_test/source/main.cpp b/source/tests/metacall_node_signal_handler_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_signal_handler_test/source/main.cpp +++ b/source/tests/metacall_node_signal_handler_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_signal_handler_test/source/metacall_node_signal_handler_test.cpp b/source/tests/metacall_node_signal_handler_test/source/metacall_node_signal_handler_test.cpp index 8dd995d8d7..61e1ef0754 100644 --- a/source/tests/metacall_node_signal_handler_test/source/metacall_node_signal_handler_test.cpp +++ b/source/tests/metacall_node_signal_handler_test/source/metacall_node_signal_handler_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -127,7 +127,7 @@ TEST_F(metacall_node_signal_handler_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); EXPECT_EQ((bool)callback_result.load(), (bool)true); EXPECT_EQ((bool)signal_result.load(), (bool)true); diff --git a/source/tests/metacall_node_test/CMakeLists.txt b/source/tests/metacall_node_test/CMakeLists.txt index c5f3c1219e..7c08d7c101 100644 --- a/source/tests/metacall_node_test/CMakeLists.txt +++ b/source/tests/metacall_node_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_node_test/source/main.cpp b/source/tests/metacall_node_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_test/source/main.cpp +++ b/source/tests/metacall_node_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_test/source/metacall_node_test.cpp b/source/tests/metacall_node_test/source/metacall_node_test.cpp index 1b7b595b61..f38954e090 100644 --- a/source/tests/metacall_node_test/source/metacall_node_test.cpp +++ b/source/tests/metacall_node_test/source/metacall_node_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -143,5 +143,5 @@ TEST_F(metacall_node_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_node_typescript_test/CMakeLists.txt b/source/tests/metacall_node_typescript_test/CMakeLists.txt index 2a0c79cccb..499baca66e 100644 --- a/source/tests/metacall_node_typescript_test/CMakeLists.txt +++ b/source/tests/metacall_node_typescript_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -122,6 +131,7 @@ target_link_libraries(${target} add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> + WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) # @@ -139,7 +149,6 @@ add_dependencies(${target} set_property(TEST ${target} PROPERTY LABELS ${target} - WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) include(TestEnvironmentVariables) diff --git a/source/tests/metacall_node_typescript_test/source/main.cpp b/source/tests/metacall_node_typescript_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_node_typescript_test/source/main.cpp +++ b/source/tests/metacall_node_typescript_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_node_typescript_test/source/metacall_node_typescript_test.cpp b/source/tests/metacall_node_typescript_test/source/metacall_node_typescript_test.cpp index 49ddae7f9d..8bf39ee566 100644 --- a/source/tests/metacall_node_typescript_test/source/metacall_node_typescript_test.cpp +++ b/source/tests/metacall_node_typescript_test/source/metacall_node_typescript_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -138,5 +138,5 @@ TEST_F(metacall_node_typescript_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_plugin_extension_destroy_order_test/CMakeLists.txt b/source/tests/metacall_plugin_extension_destroy_order_test/CMakeLists.txt index c0d8779c4d..0bf7f39890 100644 --- a/source/tests/metacall_plugin_extension_destroy_order_test/CMakeLists.txt +++ b/source/tests/metacall_plugin_extension_destroy_order_test/CMakeLists.txt @@ -118,11 +118,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_plugin_extension_destroy_order_test/source/main.cpp b/source/tests/metacall_plugin_extension_destroy_order_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_plugin_extension_destroy_order_test/source/main.cpp +++ b/source/tests/metacall_plugin_extension_destroy_order_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_plugin_extension_destroy_order_test/source/metacall_plugin_extension_destroy_order_test.cpp b/source/tests/metacall_plugin_extension_destroy_order_test/source/metacall_plugin_extension_destroy_order_test.cpp index d738fa05a0..7d094870ca 100644 --- a/source/tests/metacall_plugin_extension_destroy_order_test/source/metacall_plugin_extension_destroy_order_test.cpp +++ b/source/tests/metacall_plugin_extension_destroy_order_test/source/metacall_plugin_extension_destroy_order_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_plugin_destroy_order_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_plugin_extension_invalid_path_test/CMakeLists.txt b/source/tests/metacall_plugin_extension_invalid_path_test/CMakeLists.txt index 65eec2ce21..6e5da526f6 100644 --- a/source/tests/metacall_plugin_extension_invalid_path_test/CMakeLists.txt +++ b/source/tests/metacall_plugin_extension_invalid_path_test/CMakeLists.txt @@ -111,11 +111,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_plugin_extension_invalid_path_test/source/main.cpp b/source/tests/metacall_plugin_extension_invalid_path_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_plugin_extension_invalid_path_test/source/main.cpp +++ b/source/tests/metacall_plugin_extension_invalid_path_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_plugin_extension_invalid_path_test/source/metacall_plugin_extension_invalid_path_test.cpp b/source/tests/metacall_plugin_extension_invalid_path_test/source/metacall_plugin_extension_invalid_path_test.cpp index 56731f9960..31fec9d9b4 100644 --- a/source/tests/metacall_plugin_extension_invalid_path_test/source/metacall_plugin_extension_invalid_path_test.cpp +++ b/source/tests/metacall_plugin_extension_invalid_path_test/source/metacall_plugin_extension_invalid_path_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_plugin_extension_invalid_path_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_plugin_extension_local_test/CMakeLists.txt b/source/tests/metacall_plugin_extension_local_test/CMakeLists.txt index 3a96bccef2..174628c0ec 100644 --- a/source/tests/metacall_plugin_extension_local_test/CMakeLists.txt +++ b/source/tests/metacall_plugin_extension_local_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_plugin_extension_local_test/source/main.cpp b/source/tests/metacall_plugin_extension_local_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_plugin_extension_local_test/source/main.cpp +++ b/source/tests/metacall_plugin_extension_local_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_plugin_extension_local_test/source/metacall_plugin_extension_local_test.cpp b/source/tests/metacall_plugin_extension_local_test/source/metacall_plugin_extension_local_test.cpp index cb49d030bd..060200f35d 100644 --- a/source/tests/metacall_plugin_extension_local_test/source/metacall_plugin_extension_local_test.cpp +++ b/source/tests/metacall_plugin_extension_local_test/source/metacall_plugin_extension_local_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -119,5 +119,5 @@ TEST_F(metacall_plugin_extension_local_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_plugin_extension_test/CMakeLists.txt b/source/tests/metacall_plugin_extension_test/CMakeLists.txt index 4c4bc887c8..ed506009f8 100644 --- a/source/tests/metacall_plugin_extension_test/CMakeLists.txt +++ b/source/tests/metacall_plugin_extension_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_plugin_extension_test/source/main.cpp b/source/tests/metacall_plugin_extension_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_plugin_extension_test/source/main.cpp +++ b/source/tests/metacall_plugin_extension_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_plugin_extension_test/source/metacall_plugin_extension_test.cpp b/source/tests/metacall_plugin_extension_test/source/metacall_plugin_extension_test.cpp index 73a7269973..4d1d4ac99a 100644 --- a/source/tests/metacall_plugin_extension_test/source/metacall_plugin_extension_test.cpp +++ b/source/tests/metacall_plugin_extension_test/source/metacall_plugin_extension_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -117,5 +117,5 @@ TEST_F(metacall_plugin_extension_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_async_test/CMakeLists.txt b/source/tests/metacall_python_async_test/CMakeLists.txt index a93607cc87..c329c7a319 100644 --- a/source/tests/metacall_python_async_test/CMakeLists.txt +++ b/source/tests/metacall_python_async_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_async_test/source/metacall_python_async_test.cpp b/source/tests/metacall_python_async_test/source/metacall_python_async_test.cpp index 2b56809820..736753c3d9 100644 --- a/source/tests/metacall_python_async_test/source/metacall_python_async_test.cpp +++ b/source/tests/metacall_python_async_test/source/metacall_python_async_test.cpp @@ -160,5 +160,5 @@ TEST_F(metacall_python_async_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_await_test/CMakeLists.txt b/source/tests/metacall_python_await_test/CMakeLists.txt index 13cddb5d2e..9c34033915 100644 --- a/source/tests/metacall_python_await_test/CMakeLists.txt +++ b/source/tests/metacall_python_await_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_await_test/source/main.cpp b/source/tests/metacall_python_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_await_test/source/main.cpp +++ b/source/tests/metacall_python_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_await_test/source/metacall_python_await_test.cpp b/source/tests/metacall_python_await_test/source/metacall_python_await_test.cpp index 79d1a7d47f..71ff8b6f50 100644 --- a/source/tests/metacall_python_await_test/source/metacall_python_await_test.cpp +++ b/source/tests/metacall_python_await_test/source/metacall_python_await_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -68,5 +68,5 @@ TEST_F(metacall_python_await_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_builtins_test/CMakeLists.txt b/source/tests/metacall_python_builtins_test/CMakeLists.txt index 2e13c4e70b..698df7f4bb 100644 --- a/source/tests/metacall_python_builtins_test/CMakeLists.txt +++ b/source/tests/metacall_python_builtins_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_builtins_test/source/main.cpp b/source/tests/metacall_python_builtins_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_builtins_test/source/main.cpp +++ b/source/tests/metacall_python_builtins_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_builtins_test/source/metacall_python_builtins_test.cpp b/source/tests/metacall_python_builtins_test/source/metacall_python_builtins_test.cpp index e3fb30711f..a806d04427 100644 --- a/source/tests/metacall_python_builtins_test/source/metacall_python_builtins_test.cpp +++ b/source/tests/metacall_python_builtins_test/source/metacall_python_builtins_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_python_builtins_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_callback_test/CMakeLists.txt b/source/tests/metacall_python_callback_test/CMakeLists.txt index eab775d3e2..e576930fb8 100644 --- a/source/tests/metacall_python_callback_test/CMakeLists.txt +++ b/source/tests/metacall_python_callback_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_callback_test/source/main.cpp b/source/tests/metacall_python_callback_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_callback_test/source/main.cpp +++ b/source/tests/metacall_python_callback_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_callback_test/source/metacall_python_callback_test.cpp b/source/tests/metacall_python_callback_test/source/metacall_python_callback_test.cpp index c183c575ec..fa15992d94 100644 --- a/source/tests/metacall_python_callback_test/source/metacall_python_callback_test.cpp +++ b/source/tests/metacall_python_callback_test/source/metacall_python_callback_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -66,5 +66,5 @@ TEST_F(metacall_python_callback_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_dict_test/CMakeLists.txt b/source/tests/metacall_python_dict_test/CMakeLists.txt index ed59ef059a..835a24fed9 100644 --- a/source/tests/metacall_python_dict_test/CMakeLists.txt +++ b/source/tests/metacall_python_dict_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_dict_test/source/main.cpp b/source/tests/metacall_python_dict_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_dict_test/source/main.cpp +++ b/source/tests/metacall_python_dict_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 af0ec1aa53..f5db7671ce 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -169,5 +169,5 @@ TEST_F(metacall_python_dict_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_exception_test/CMakeLists.txt b/source/tests/metacall_python_exception_test/CMakeLists.txt index 85f131f27b..e06790523f 100644 --- a/source/tests/metacall_python_exception_test/CMakeLists.txt +++ b/source/tests/metacall_python_exception_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_exception_test/source/main.cpp b/source/tests/metacall_python_exception_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_exception_test/source/main.cpp +++ b/source/tests/metacall_python_exception_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 1a5f92cec2..14ec35d757 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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,13 +64,13 @@ 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); } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_fail_test/CMakeLists.txt b/source/tests/metacall_python_fail_test/CMakeLists.txt index 73c4b15a8d..d16a571d28 100644 --- a/source/tests/metacall_python_fail_test/CMakeLists.txt +++ b/source/tests/metacall_python_fail_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_fail_test/source/main.cpp b/source/tests/metacall_python_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_fail_test/source/main.cpp +++ b/source/tests/metacall_python_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_fail_test/source/metacall_python_fail_test.cpp b/source/tests/metacall_python_fail_test/source/metacall_python_fail_test.cpp index b36822b37a..7ef4531f60 100644 --- a/source/tests/metacall_python_fail_test/source/metacall_python_fail_test.cpp +++ b/source/tests/metacall_python_fail_test/source/metacall_python_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -93,5 +93,5 @@ TEST_F(metacall_python_fail_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_gc_test/CMakeLists.txt b/source/tests/metacall_python_gc_test/CMakeLists.txt index 01d197adaf..b726024342 100644 --- a/source/tests/metacall_python_gc_test/CMakeLists.txt +++ b/source/tests/metacall_python_gc_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_gc_test/source/main.cpp b/source/tests/metacall_python_gc_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_gc_test/source/main.cpp +++ b/source/tests/metacall_python_gc_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_gc_test/source/metacall_python_gc_test.cpp b/source/tests/metacall_python_gc_test/source/metacall_python_gc_test.cpp index 14e5fdc741..8bdea252fb 100644 --- a/source/tests/metacall_python_gc_test/source/metacall_python_gc_test.cpp +++ b/source/tests/metacall_python_gc_test/source/metacall_python_gc_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -45,9 +45,9 @@ TEST_F(metacall_python_gc_test, DefaultConstructor) void *ret = metacall("set_debug"); - EXPECT_NE((void *)NULL, (void *)ret); + ASSERT_NE((void *)NULL, (void *)ret); - EXPECT_EQ((enum metacall_value_id)METACALL_NULL, (enum metacall_value_id)metacall_value_id(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_NULL, (enum metacall_value_id)metacall_value_id(ret)); EXPECT_EQ((void *)NULL, (void *)metacall_value_to_null(ret)); @@ -57,11 +57,13 @@ TEST_F(metacall_python_gc_test, DefaultConstructor) ASSERT_NE((void *)NULL, (void *)ret); + ASSERT_EQ((enum metacall_value_id)METACALL_STRING, (enum metacall_value_id)metacall_value_id(ret)); + std::cout << metacall_value_to_string(ret) << std::endl; metacall_value_destroy(ret); } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_loader_port_test/CMakeLists.txt b/source/tests/metacall_python_loader_port_test/CMakeLists.txt index e1c2b3f45f..eed75ba06a 100644 --- a/source/tests/metacall_python_loader_port_test/CMakeLists.txt +++ b/source/tests/metacall_python_loader_port_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_loader_port_test/source/main.cpp b/source/tests/metacall_python_loader_port_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_loader_port_test/source/main.cpp +++ b/source/tests/metacall_python_loader_port_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 05619bf636..ffa9043263 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 @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -131,5 +131,5 @@ TEST_F(metacall_python_loader_port_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_model_test/CMakeLists.txt b/source/tests/metacall_python_model_test/CMakeLists.txt index d7d554d845..01475c8c83 100644 --- a/source/tests/metacall_python_model_test/CMakeLists.txt +++ b/source/tests/metacall_python_model_test/CMakeLists.txt @@ -118,11 +118,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_model_test/source/main.cpp b/source/tests/metacall_python_model_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_model_test/source/main.cpp +++ b/source/tests/metacall_python_model_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_model_test/source/metacall_python_model_test.cpp b/source/tests/metacall_python_model_test/source/metacall_python_model_test.cpp index 1ab58c5db3..ca200e45b8 100644 --- a/source/tests/metacall_python_model_test/source/metacall_python_model_test.cpp +++ b/source/tests/metacall_python_model_test/source/metacall_python_model_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -82,5 +82,5 @@ TEST_F(metacall_python_model_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_node_await_test/CMakeLists.txt b/source/tests/metacall_python_node_await_test/CMakeLists.txt index 4b2cb58b31..e2d89c8ffc 100644 --- a/source/tests/metacall_python_node_await_test/CMakeLists.txt +++ b/source/tests/metacall_python_node_await_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_node_await_test/source/main.cpp b/source/tests/metacall_python_node_await_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_node_await_test/source/main.cpp +++ b/source/tests/metacall_python_node_await_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_node_await_test/source/metacall_python_node_await_test.cpp b/source/tests/metacall_python_node_await_test/source/metacall_python_node_await_test.cpp index 5b1d15b30a..168f3517c4 100644 --- a/source/tests/metacall_python_node_await_test/source/metacall_python_node_await_test.cpp +++ b/source/tests/metacall_python_node_await_test/source/metacall_python_node_await_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -71,5 +71,5 @@ TEST_F(metacall_python_node_await_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_NODE && OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_object_class_test/CMakeLists.txt b/source/tests/metacall_python_object_class_test/CMakeLists.txt index 0fb055b612..f81c535ee8 100644 --- a/source/tests/metacall_python_object_class_test/CMakeLists.txt +++ b/source/tests/metacall_python_object_class_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_object_class_test/source/main.cpp b/source/tests/metacall_python_object_class_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_object_class_test/source/main.cpp +++ b/source/tests/metacall_python_object_class_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_object_class_test/source/metacall_python_object_class_test.cpp b/source/tests/metacall_python_object_class_test/source/metacall_python_object_class_test.cpp index c2117aeb1b..092c58927c 100644 --- a/source/tests/metacall_python_object_class_test/source/metacall_python_object_class_test.cpp +++ b/source/tests/metacall_python_object_class_test/source/metacall_python_object_class_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -149,6 +149,24 @@ TEST_F(metacall_python_class_test, DefaultConstructor) ASSERT_EQ((enum metacall_value_id)METACALL_STRING, (enum metacall_value_id)metacall_value_id(ret_value)); metacall_value_destroy(static_method_args[0]); metacall_value_destroy(ret_value); + + // Get and Set + void *param2 = metacall_class_static_get(myclass, "b"); + ASSERT_EQ((enum metacall_value_id)METACALL_LONG, (enum metacall_value_id)metacall_value_id(param2)); + ASSERT_EQ((long)44444L, (long)metacall_value_to_long(param2)); + + metacall_value_destroy(param2); + + void *long_value = metacall_value_create_long(5555L); + int retcode = metacall_class_static_set(myclass, "b", long_value); + metacall_value_destroy(long_value); + ASSERT_EQ((int)0, int(retcode)); + + param2 = metacall_class_static_get(myclass, "b"); + ASSERT_EQ((enum metacall_value_id)METACALL_LONG, (enum metacall_value_id)metacall_value_id(param2)); + ASSERT_EQ((long)5555L, (long)metacall_value_to_long(param2)); + + metacall_value_destroy(param2); } { @@ -203,5 +221,5 @@ TEST_F(metacall_python_class_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_open_test/CMakeLists.txt b/source/tests/metacall_python_open_test/CMakeLists.txt index 2011c17a79..32959b3635 100644 --- a/source/tests/metacall_python_open_test/CMakeLists.txt +++ b/source/tests/metacall_python_open_test/CMakeLists.txt @@ -127,11 +127,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_open_test/source/main.cpp b/source/tests/metacall_python_open_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_open_test/source/main.cpp +++ b/source/tests/metacall_python_open_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 0a273681ef..0174eb61f5 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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]); @@ -94,5 +94,5 @@ TEST_F(metacall_python_open_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_pointer_test/CMakeLists.txt b/source/tests/metacall_python_pointer_test/CMakeLists.txt index 911c8d2e8e..fe6f4ee616 100644 --- a/source/tests/metacall_python_pointer_test/CMakeLists.txt +++ b/source/tests/metacall_python_pointer_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_pointer_test/source/main.cpp b/source/tests/metacall_python_pointer_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_pointer_test/source/main.cpp +++ b/source/tests/metacall_python_pointer_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_pointer_test/source/metacall_python_pointer_test.cpp b/source/tests/metacall_python_pointer_test/source/metacall_python_pointer_test.cpp index 863ab1cdd0..cd7edd2e2d 100644 --- a/source/tests/metacall_python_pointer_test/source/metacall_python_pointer_test.cpp +++ b/source/tests/metacall_python_pointer_test/source/metacall_python_pointer_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -160,5 +160,5 @@ TEST_F(metacall_python_pointer_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_port_callback_test/CMakeLists.txt b/source/tests/metacall_python_port_callback_test/CMakeLists.txt index c2d356b145..bbf27070a8 100644 --- a/source/tests/metacall_python_port_callback_test/CMakeLists.txt +++ b/source/tests/metacall_python_port_callback_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_port_callback_test/source/main.cpp b/source/tests/metacall_python_port_callback_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_port_callback_test/source/main.cpp +++ b/source/tests/metacall_python_port_callback_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_port_callback_test/source/metacall_python_port_callback_test.cpp b/source/tests/metacall_python_port_callback_test/source/metacall_python_port_callback_test.cpp index b3f5b8598f..c0fd5e5b21 100644 --- a/source/tests/metacall_python_port_callback_test/source/metacall_python_port_callback_test.cpp +++ b/source/tests/metacall_python_port_callback_test/source/metacall_python_port_callback_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -67,5 +67,5 @@ TEST_F(metacall_python_port_callback_test, DefaultConstructor) metacall_value_destroy(ret); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_port_https_test/CMakeLists.txt b/source/tests/metacall_python_port_https_test/CMakeLists.txt index 5760efabcd..1f1335666e 100644 --- a/source/tests/metacall_python_port_https_test/CMakeLists.txt +++ b/source/tests/metacall_python_port_https_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_port_https_test/source/main.cpp b/source/tests/metacall_python_port_https_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_port_https_test/source/main.cpp +++ b/source/tests/metacall_python_port_https_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_port_https_test/source/metacall_python_port_https_test.cpp b/source/tests/metacall_python_port_https_test/source/metacall_python_port_https_test.cpp index f552efa14b..e6082d2fe9 100644 --- a/source/tests/metacall_python_port_https_test/source/metacall_python_port_https_test.cpp +++ b/source/tests/metacall_python_port_https_test/source/metacall_python_port_https_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -71,5 +71,5 @@ TEST_F(metacall_python_port_https_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_port_import_test/CMakeLists.txt b/source/tests/metacall_python_port_import_test/CMakeLists.txt index 68b706515f..051f059533 100644 --- a/source/tests/metacall_python_port_import_test/CMakeLists.txt +++ b/source/tests/metacall_python_port_import_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_port_import_test/source/main.cpp b/source/tests/metacall_python_port_import_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_port_import_test/source/main.cpp +++ b/source/tests/metacall_python_port_import_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_port_import_test/source/metacall_python_port_import_test.cpp b/source/tests/metacall_python_port_import_test/source/metacall_python_port_import_test.cpp index bfb2fa4e8f..23b93ca1a4 100644 --- a/source/tests/metacall_python_port_import_test/source/metacall_python_port_import_test.cpp +++ b/source/tests/metacall_python_port_import_test/source/metacall_python_port_import_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -118,5 +118,5 @@ TEST_F(metacall_python_port_import_test, metacall_node_ramda_case_1) ASSERT_NE((void *)handle, (void *)NULL); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_port_pointer_test/CMakeLists.txt b/source/tests/metacall_python_port_pointer_test/CMakeLists.txt index d421bdbe79..2c4133672e 100644 --- a/source/tests/metacall_python_port_pointer_test/CMakeLists.txt +++ b/source/tests/metacall_python_port_pointer_test/CMakeLists.txt @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_port_pointer_test/source/main.cpp b/source/tests/metacall_python_port_pointer_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_port_pointer_test/source/main.cpp +++ b/source/tests/metacall_python_port_pointer_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_port_pointer_test/source/metacall_python_port_pointer_test.cpp b/source/tests/metacall_python_port_pointer_test/source/metacall_python_port_pointer_test.cpp index b2d57db4bb..fd6214d1d5 100644 --- a/source/tests/metacall_python_port_pointer_test/source/metacall_python_port_pointer_test.cpp +++ b/source/tests/metacall_python_port_pointer_test/source/metacall_python_port_pointer_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -118,5 +118,5 @@ TEST_F(metacall_python_port_pointer_test, DefaultConstructor) metacall_value_destroy(ret); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_port_test/CMakeLists.txt b/source/tests/metacall_python_port_test/CMakeLists.txt index ca0c027db5..124502f07b 100644 --- a/source/tests/metacall_python_port_test/CMakeLists.txt +++ b/source/tests/metacall_python_port_test/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if loaders are enabled -if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_LOADERS_RS OR NOT OPTION_BUILD_PORTS OR NOT OPTION_BUILD_PORTS_PY OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB OR NOT OPTION_BUILD_SCRIPTS_RS OR NOT OPTION_BUILD_SCRIPTS_NODE) +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_PY OR NOT OPTION_BUILD_LOADERS_RB OR NOT OPTION_BUILD_LOADERS_NODE OR NOT OPTION_BUILD_PORTS OR NOT OPTION_BUILD_PORTS_PY OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_PY OR NOT OPTION_BUILD_SCRIPTS_RB OR NOT OPTION_BUILD_SCRIPTS_NODE) return() endif() @@ -109,11 +109,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -126,6 +135,12 @@ add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> ) +# Enable rust test if it is built +if(OPTION_BUILD_LOADERS_RS) + set(RS_DEPENDENCY rs_loader) + set(TESTS_ENVIRONMENT_VARIABLES_RS "OPTION_BUILD_LOADERS_RS=1") +endif() + # # Define dependencies # @@ -135,6 +150,7 @@ add_dependencies(${target} py_loader rb_loader node_loader + ${RS_DEPENDENCY} ) # @@ -150,4 +166,5 @@ include(TestEnvironmentVariables) test_environment_variables(${target} "" ${TESTS_ENVIRONMENT_VARIABLES} + ${TESTS_ENVIRONMENT_VARIABLES_RS} ) diff --git a/source/tests/metacall_python_port_test/source/main.cpp b/source/tests/metacall_python_port_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_port_test/source/main.cpp +++ b/source/tests/metacall_python_port_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 e901d72456..7ebb7c236e 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -46,11 +46,11 @@ 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); } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_reentrant_test/CMakeLists.txt b/source/tests/metacall_python_reentrant_test/CMakeLists.txt index 727a99c1df..ab29592ef2 100644 --- a/source/tests/metacall_python_reentrant_test/CMakeLists.txt +++ b/source/tests/metacall_python_reentrant_test/CMakeLists.txt @@ -110,11 +110,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_reentrant_test/source/main.cpp b/source/tests/metacall_python_reentrant_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_reentrant_test/source/main.cpp +++ b/source/tests/metacall_python_reentrant_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_reentrant_test/source/metacall_python_reentrant_test.cpp b/source/tests/metacall_python_reentrant_test/source/metacall_python_reentrant_test.cpp index 33328a637e..ae1d107591 100644 --- a/source/tests/metacall_python_reentrant_test/source/metacall_python_reentrant_test.cpp +++ b/source/tests/metacall_python_reentrant_test/source/metacall_python_reentrant_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -76,5 +76,5 @@ TEST_F(metacall_python_reentrant_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_relative_path_test/CMakeLists.txt b/source/tests/metacall_python_relative_path_test/CMakeLists.txt index 667570f675..22cae4f281 100644 --- a/source/tests/metacall_python_relative_path_test/CMakeLists.txt +++ b/source/tests/metacall_python_relative_path_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_relative_path_test/source/main.cpp b/source/tests/metacall_python_relative_path_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_relative_path_test/source/main.cpp +++ b/source/tests/metacall_python_relative_path_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_relative_path_test/source/metacall_python_relative_path_test.cpp b/source/tests/metacall_python_relative_path_test/source/metacall_python_relative_path_test.cpp index 5d0505a560..0c44179d68 100644 --- a/source/tests/metacall_python_relative_path_test/source/metacall_python_relative_path_test.cpp +++ b/source/tests/metacall_python_relative_path_test/source/metacall_python_relative_path_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -72,5 +72,5 @@ TEST_F(metacall_python_dict_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_test/CMakeLists.txt b/source/tests/metacall_python_test/CMakeLists.txt index 6302b85c2a..6f89617e34 100644 --- a/source/tests/metacall_python_test/CMakeLists.txt +++ b/source/tests/metacall_python_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_test/source/main.cpp b/source/tests/metacall_python_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_test/source/main.cpp +++ b/source/tests/metacall_python_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_test/source/metacall_python_test.cpp b/source/tests/metacall_python_test/source/metacall_python_test.cpp index 97a6bb3efb..690bf226af 100644 --- a/source/tests/metacall_python_test/source/metacall_python_test.cpp +++ b/source/tests/metacall_python_test/source/metacall_python_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_python_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_varargs_test/CMakeLists.txt b/source/tests/metacall_python_varargs_test/CMakeLists.txt index 4fa048b647..f8636d21e2 100644 --- a/source/tests/metacall_python_varargs_test/CMakeLists.txt +++ b/source/tests/metacall_python_varargs_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_varargs_test/source/main.cpp b/source/tests/metacall_python_varargs_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_varargs_test/source/main.cpp +++ b/source/tests/metacall_python_varargs_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_varargs_test/source/metacall_python_varargs_test.cpp b/source/tests/metacall_python_varargs_test/source/metacall_python_varargs_test.cpp index 539c7e02bd..e640a1f50f 100644 --- a/source/tests/metacall_python_varargs_test/source/metacall_python_varargs_test.cpp +++ b/source/tests/metacall_python_varargs_test/source/metacall_python_varargs_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -102,5 +102,5 @@ TEST_F(metacall_python_varargs_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_without_env_vars_test/CMakeLists.txt b/source/tests/metacall_python_without_env_vars_test/CMakeLists.txt index 5ffd8ffed4..3aca8756e3 100644 --- a/source/tests/metacall_python_without_env_vars_test/CMakeLists.txt +++ b/source/tests/metacall_python_without_env_vars_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_without_env_vars_test/source/main.cpp b/source/tests/metacall_python_without_env_vars_test/source/main.cpp index 3f4f3377f9..7832a63230 100644 --- a/source/tests/metacall_python_without_env_vars_test/source/main.cpp +++ b/source/tests/metacall_python_without_env_vars_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_without_env_vars_test/source/metacall_python_without_env_vars_test.cpp b/source/tests/metacall_python_without_env_vars_test/source/metacall_python_without_env_vars_test.cpp index 7a0c6c1184..05ec480890 100644 --- a/source/tests/metacall_python_without_env_vars_test/source/metacall_python_without_env_vars_test.cpp +++ b/source/tests/metacall_python_without_env_vars_test/source/metacall_python_without_env_vars_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading python code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -45,5 +45,5 @@ TEST_F(metacall_python_without_env_vars_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_PY */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_python_without_functions_test/CMakeLists.txt b/source/tests/metacall_python_without_functions_test/CMakeLists.txt index 47b97fb0af..e2092380eb 100644 --- a/source/tests/metacall_python_without_functions_test/CMakeLists.txt +++ b/source/tests/metacall_python_without_functions_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_python_without_functions_test/source/main.cpp b/source/tests/metacall_python_without_functions_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_python_without_functions_test/source/main.cpp +++ b/source/tests/metacall_python_without_functions_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_python_without_functions_test/source/metacall_python_without_functions_test.cpp b/source/tests/metacall_python_without_functions_test/source/metacall_python_without_functions_test.cpp index 8dd69eafa0..9e84dbe510 100644 --- a/source/tests/metacall_python_without_functions_test/source/metacall_python_without_functions_test.cpp +++ b/source/tests/metacall_python_without_functions_test/source/metacall_python_without_functions_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -66,5 +66,5 @@ TEST_F(metacall_python_without_functions_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_reinitialize_test/CMakeLists.txt b/source/tests/metacall_reinitialize_test/CMakeLists.txt index 82aa0d9627..c1adf593e3 100644 --- a/source/tests/metacall_reinitialize_test/CMakeLists.txt +++ b/source/tests/metacall_reinitialize_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_reinitialize_test/source/main.cpp b/source/tests/metacall_reinitialize_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_reinitialize_test/source/main.cpp +++ b/source/tests/metacall_reinitialize_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_reinitialize_test/source/metacall_reinitialize_test.cpp b/source/tests/metacall_reinitialize_test/source/metacall_reinitialize_test.cpp index e1324ba7f3..da47af9905 100644 --- a/source/tests/metacall_reinitialize_test/source/metacall_reinitialize_test.cpp +++ b/source/tests/metacall_reinitialize_test/source/metacall_reinitialize_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -61,6 +61,6 @@ TEST_F(metacall_reinitialize_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_MOCK */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } } diff --git a/source/tests/metacall_reload_functions_test/CMakeLists.txt b/source/tests/metacall_reload_functions_test/CMakeLists.txt index 07845beb42..8d7682d2ce 100644 --- a/source/tests/metacall_reload_functions_test/CMakeLists.txt +++ b/source/tests/metacall_reload_functions_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_reload_functions_test/source/main.cpp b/source/tests/metacall_reload_functions_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_reload_functions_test/source/main.cpp +++ b/source/tests/metacall_reload_functions_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_reload_functions_test/source/metacall_reload_functions_test.cpp b/source/tests/metacall_reload_functions_test/source/metacall_reload_functions_test.cpp index 85fee11c54..be227cf3d4 100644 --- a/source/tests/metacall_reload_functions_test/source/metacall_reload_functions_test.cpp +++ b/source/tests/metacall_reload_functions_test/source/metacall_reload_functions_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -170,5 +170,5 @@ TEST_F(metacall_reload_functions_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_return_monad_test/CMakeLists.txt b/source/tests/metacall_return_monad_test/CMakeLists.txt index 94aa6644fc..bcf5ad5c57 100644 --- a/source/tests/metacall_return_monad_test/CMakeLists.txt +++ b/source/tests/metacall_return_monad_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_return_monad_test/source/main.cpp b/source/tests/metacall_return_monad_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_return_monad_test/source/main.cpp +++ b/source/tests/metacall_return_monad_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 63b65fe2f5..5194d3ab86 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); @@ -129,5 +129,5 @@ TEST_F(metacall_return_monad_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rpc_test/CMakeLists.txt b/source/tests/metacall_rpc_test/CMakeLists.txt index 78553d0e85..04925f1f1c 100644 --- a/source/tests/metacall_rpc_test/CMakeLists.txt +++ b/source/tests/metacall_rpc_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rpc_test/source/main.cpp b/source/tests/metacall_rpc_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_rpc_test/source/main.cpp +++ b/source/tests/metacall_rpc_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_rpc_test/source/metacall_rpc_test.cpp b/source/tests/metacall_rpc_test/source/metacall_rpc_test.cpp index 0984befcd2..670911293b 100644 --- a/source/tests/metacall_rpc_test/source/metacall_rpc_test.cpp +++ b/source/tests/metacall_rpc_test/source/metacall_rpc_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -87,5 +87,5 @@ TEST_F(metacall_rpc_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_RPC */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rpc_test/source/test.js b/source/tests/metacall_rpc_test/source/test.js index 42c12bd331..15d5a9dac5 100644 --- a/source/tests/metacall_rpc_test/source/test.js +++ b/source/tests/metacall_rpc_test/source/test.js @@ -62,7 +62,7 @@ process.on('uncaughtException', killTest); if (ready === false) { killTest('Timeout reached, server is not ready'); } - }, 10000); + }, 60000); while (ready !== true) { try { diff --git a/source/tests/metacall_ruby_fail_empty_test/CMakeLists.txt b/source/tests/metacall_ruby_fail_empty_test/CMakeLists.txt index 5881420602..a480292e1c 100644 --- a/source/tests/metacall_ruby_fail_empty_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_fail_empty_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_fail_empty_test/source/main.cpp b/source/tests/metacall_ruby_fail_empty_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ruby_fail_empty_test/source/main.cpp +++ b/source/tests/metacall_ruby_fail_empty_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ruby_fail_empty_test/source/metacall_ruby_fail_empty_test.cpp b/source/tests/metacall_ruby_fail_empty_test/source/metacall_ruby_fail_empty_test.cpp index b9cb7dfd26..5ab21e63e2 100644 --- a/source/tests/metacall_ruby_fail_empty_test/source/metacall_ruby_fail_empty_test.cpp +++ b/source/tests/metacall_ruby_fail_empty_test/source/metacall_ruby_fail_empty_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -69,5 +69,5 @@ TEST_F(metacall_ruby_fail_empty_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ruby_fail_test/CMakeLists.txt b/source/tests/metacall_ruby_fail_test/CMakeLists.txt index 375bfffeef..a34d4318cd 100644 --- a/source/tests/metacall_ruby_fail_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_fail_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_fail_test/source/main.cpp b/source/tests/metacall_ruby_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ruby_fail_test/source/main.cpp +++ b/source/tests/metacall_ruby_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ruby_fail_test/source/metacall_ruby_fail_test.cpp b/source/tests/metacall_ruby_fail_test/source/metacall_ruby_fail_test.cpp index b7228a7e94..24c11d7981 100644 --- a/source/tests/metacall_ruby_fail_test/source/metacall_ruby_fail_test.cpp +++ b/source/tests/metacall_ruby_fail_test/source/metacall_ruby_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -50,5 +50,5 @@ TEST_F(metacall_ruby_fail_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_RB */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ruby_object_class_test/CMakeLists.txt b/source/tests/metacall_ruby_object_class_test/CMakeLists.txt index 3467e71653..c4d2ad9b38 100644 --- a/source/tests/metacall_ruby_object_class_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_object_class_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_object_class_test/source/main.cpp b/source/tests/metacall_ruby_object_class_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ruby_object_class_test/source/main.cpp +++ b/source/tests/metacall_ruby_object_class_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ruby_object_class_test/source/metacall_ruby_object_class_test.cpp b/source/tests/metacall_ruby_object_class_test/source/metacall_ruby_object_class_test.cpp index ca8ca3c142..05d7f272cb 100644 --- a/source/tests/metacall_ruby_object_class_test/source/metacall_ruby_object_class_test.cpp +++ b/source/tests/metacall_ruby_object_class_test/source/metacall_ruby_object_class_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -160,5 +160,5 @@ TEST_F(metacall_ruby_object_class_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ruby_parser_integration_test/CMakeLists.txt b/source/tests/metacall_ruby_parser_integration_test/CMakeLists.txt index 9cabe6b27b..ecd892ffb0 100644 --- a/source/tests/metacall_ruby_parser_integration_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_parser_integration_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_parser_integration_test/source/main.cpp b/source/tests/metacall_ruby_parser_integration_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ruby_parser_integration_test/source/main.cpp +++ b/source/tests/metacall_ruby_parser_integration_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 e9fd2d082f..0e38e65ac9 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -74,11 +74,11 @@ 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); } #endif /* OPTION_BUILD_LOADERS_RB */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ruby_rails_integration_test/CMakeLists.txt b/source/tests/metacall_ruby_rails_integration_test/CMakeLists.txt index fd57bc5239..6559f627a6 100644 --- a/source/tests/metacall_ruby_rails_integration_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_rails_integration_test/CMakeLists.txt @@ -114,11 +114,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_rails_integration_test/source/main.cpp b/source/tests/metacall_ruby_rails_integration_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_ruby_rails_integration_test/source/main.cpp +++ b/source/tests/metacall_ruby_rails_integration_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ruby_rails_integration_test/source/metacall_ruby_rails_integration_test.cpp b/source/tests/metacall_ruby_rails_integration_test/source/metacall_ruby_rails_integration_test.cpp index 91fb3fb4c4..5d04ac4351 100644 --- a/source/tests/metacall_ruby_rails_integration_test/source/metacall_ruby_rails_integration_test.cpp +++ b/source/tests/metacall_ruby_rails_integration_test/source/metacall_ruby_rails_integration_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -59,5 +59,5 @@ TEST_F(metacall_ruby_integration_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_RB */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_ruby_test/CMakeLists.txt b/source/tests/metacall_ruby_test/CMakeLists.txt index e954b12fdb..163c170a64 100644 --- a/source/tests/metacall_ruby_test/CMakeLists.txt +++ b/source/tests/metacall_ruby_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_ruby_test/source/main.cpp b/source/tests/metacall_ruby_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_ruby_test/source/main.cpp +++ b/source/tests/metacall_ruby_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_ruby_test/source/metacall_ruby_test.cpp b/source/tests/metacall_ruby_test/source/metacall_ruby_test.cpp index e22eb5dbbd..cf8bcf49ea 100644 --- a/source/tests/metacall_ruby_test/source/metacall_ruby_test.cpp +++ b/source/tests/metacall_ruby_test/source/metacall_ruby_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -37,5 +37,5 @@ TEST_F(metacall_ruby_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_load_from_file("rb", rb_scripts, sizeof(rb_scripts) / sizeof(rb_scripts[0]), NULL)); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_class_test/CMakeLists.txt b/source/tests/metacall_rust_class_test/CMakeLists.txt index 46e5e89533..28a7f1dac5 100644 --- a/source/tests/metacall_rust_class_test/CMakeLists.txt +++ b/source/tests/metacall_rust_class_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_class_test/source/main.cpp b/source/tests/metacall_rust_class_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_class_test/source/main.cpp +++ b/source/tests/metacall_rust_class_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_rust_class_test/source/metacall_rust_class_test.cpp b/source/tests/metacall_rust_class_test/source/metacall_rust_class_test.cpp index 64d4627bfa..235841a990 100644 --- a/source/tests/metacall_rust_class_test/source/metacall_rust_class_test.cpp +++ b/source/tests/metacall_rust_class_test/source/metacall_rust_class_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -103,5 +103,5 @@ TEST_F(metacall_rust_class_test, DefaultConstructor) // metacall_value_destroy(book_class); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_load_from_mem_test/CMakeLists.txt b/source/tests/metacall_rust_load_from_mem_test/CMakeLists.txt index e873e59af2..026115ba3b 100644 --- a/source/tests/metacall_rust_load_from_mem_test/CMakeLists.txt +++ b/source/tests/metacall_rust_load_from_mem_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_load_from_mem_test/source/main.cpp b/source/tests/metacall_rust_load_from_mem_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_load_from_mem_test/source/main.cpp +++ b/source/tests/metacall_rust_load_from_mem_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_rust_load_from_mem_test/source/metacall_rust_load_from_mem_test.cpp b/source/tests/metacall_rust_load_from_mem_test/source/metacall_rust_load_from_mem_test.cpp index fccdcee342..ab09ed72b5 100644 --- a/source/tests/metacall_rust_load_from_mem_test/source/metacall_rust_load_from_mem_test.cpp +++ b/source/tests/metacall_rust_load_from_mem_test/source/metacall_rust_load_from_mem_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -69,5 +69,5 @@ TEST_F(metacall_rust_load_from_mem_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_load_from_package_class_test/CMakeLists.txt b/source/tests/metacall_rust_load_from_package_class_test/CMakeLists.txt index 1d06c81f34..0f98b613a9 100644 --- a/source/tests/metacall_rust_load_from_package_class_test/CMakeLists.txt +++ b/source/tests/metacall_rust_load_from_package_class_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_load_from_package_class_test/source/main.cpp b/source/tests/metacall_rust_load_from_package_class_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_load_from_package_class_test/source/main.cpp +++ b/source/tests/metacall_rust_load_from_package_class_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_rust_load_from_package_class_test/source/metacall_rust_load_from_package_class_test.cpp b/source/tests/metacall_rust_load_from_package_class_test/source/metacall_rust_load_from_package_class_test.cpp index db6f6de38f..d4f927d5b2 100644 --- a/source/tests/metacall_rust_load_from_package_class_test/source/metacall_rust_load_from_package_class_test.cpp +++ b/source/tests/metacall_rust_load_from_package_class_test/source/metacall_rust_load_from_package_class_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -102,5 +102,5 @@ TEST_F(metacall_rust_load_from_mem_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_load_from_package_dep_test/CMakeLists.txt b/source/tests/metacall_rust_load_from_package_dep_test/CMakeLists.txt index 4c4e3d8b97..7ac9429cf3 100644 --- a/source/tests/metacall_rust_load_from_package_dep_test/CMakeLists.txt +++ b/source/tests/metacall_rust_load_from_package_dep_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_load_from_package_dep_test/source/main.cpp b/source/tests/metacall_rust_load_from_package_dep_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_load_from_package_dep_test/source/main.cpp +++ b/source/tests/metacall_rust_load_from_package_dep_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 c239fd1cc1..565883bc28 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 @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -65,5 +65,5 @@ TEST_F(metacall_rust_load_from_package_dep_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_load_from_package_test/CMakeLists.txt b/source/tests/metacall_rust_load_from_package_test/CMakeLists.txt index 8a938e3003..a5aaabbe66 100644 --- a/source/tests/metacall_rust_load_from_package_test/CMakeLists.txt +++ b/source/tests/metacall_rust_load_from_package_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_load_from_package_test/source/main.cpp b/source/tests/metacall_rust_load_from_package_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_load_from_package_test/source/main.cpp +++ b/source/tests/metacall_rust_load_from_package_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 7f639f4bcf..cfb3b49957 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 @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); // } @@ -168,5 +168,5 @@ TEST_F(metacall_rust_load_from_mem_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_rust_test/CMakeLists.txt b/source/tests/metacall_rust_test/CMakeLists.txt index c868f44c31..31434b1be3 100644 --- a/source/tests/metacall_rust_test/CMakeLists.txt +++ b/source/tests/metacall_rust_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_rust_test/source/main.cpp b/source/tests/metacall_rust_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/metacall_rust_test/source/main.cpp +++ b/source/tests/metacall_rust_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 cbe3e2ef91..55736c73e2 100644 --- a/source/tests/metacall_rust_test/source/metacall_rust_test.cpp +++ b/source/tests/metacall_rust_test/source/metacall_rust_test.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -187,5 +187,5 @@ TEST_F(metacall_rust_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_sandbox_plugin_test/CMakeLists.txt b/source/tests/metacall_sandbox_plugin_test/CMakeLists.txt index e6c39e7924..3a98235b10 100644 --- a/source/tests/metacall_sandbox_plugin_test/CMakeLists.txt +++ b/source/tests/metacall_sandbox_plugin_test/CMakeLists.txt @@ -123,11 +123,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_sandbox_plugin_test/source/main.cpp b/source/tests/metacall_sandbox_plugin_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_sandbox_plugin_test/source/main.cpp +++ b/source/tests/metacall_sandbox_plugin_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_sandbox_plugin_test/source/metacall_sandbox_plugin_test.cpp b/source/tests/metacall_sandbox_plugin_test/source/metacall_sandbox_plugin_test.cpp index 824da2ae1a..3cd32dcf0f 100644 --- a/source/tests/metacall_sandbox_plugin_test/source/metacall_sandbox_plugin_test.cpp +++ b/source/tests/metacall_sandbox_plugin_test/source/metacall_sandbox_plugin_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -291,7 +291,7 @@ TEST_F(metacall_sandbox_plugin_test, DefaultConstructor) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } /* [Note] This test blocks all the gtest context, so you should comment it to allow testing for other test cases */ @@ -330,7 +330,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_IO_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_SOCKETS_DISABLE_TEST) @@ -381,7 +381,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_SOCKETS_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_IPC_DISABLE_TEST) @@ -432,7 +432,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_IPC_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_PROCESS_DISABLE_TEST) @@ -470,7 +470,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_PROCESS_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_FILESYSTEMS_DISABLE_TEST) @@ -508,7 +508,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_FILESYSTEMS_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_TIME_DISABLE_TEST) @@ -559,7 +559,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_TIME_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_MEMORY_DISABLE_TEST) @@ -597,7 +597,7 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_MEMORY_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } TEST_F(metacall_sandbox_plugin_test, SANDBOX_SIGNALS_DISABLE_TEST) @@ -648,5 +648,5 @@ TEST_F(metacall_sandbox_plugin_test, SANDBOX_SIGNALS_DISABLE_TEST) metacall_value_destroy(args[0]); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_test/CMakeLists.txt b/source/tests/metacall_test/CMakeLists.txt index b9afa8da8d..8751e1fe0e 100644 --- a/source/tests/metacall_test/CMakeLists.txt +++ b/source/tests/metacall_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_test/source/main.cpp b/source/tests/metacall_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_test/source/main.cpp +++ b/source/tests/metacall_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_test/source/metacall_test.cpp b/source/tests/metacall_test/source/metacall_test.cpp index 4deebb1501..ddbf10c03b 100644 --- a/source/tests/metacall_test/source/metacall_test.cpp +++ b/source/tests/metacall_test/source/metacall_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -605,5 +605,5 @@ TEST_F(metacall_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_test/source/metacall_test_split.cpp b/source/tests/metacall_test/source/metacall_test_split.cpp index 1064365b1e..0a19bce6a1 100644 --- a/source/tests/metacall_test/source/metacall_test_split.cpp +++ b/source/tests/metacall_test/source/metacall_test_split.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -44,7 +44,7 @@ TEST_F(metacall_test, DefaultConstructor) EXPECT_EQ((int)0, (int)metacall_initialize()); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } class metacall_loader_test : public testing::Test @@ -63,7 +63,7 @@ class metacall_loader_test : public testing::Test ~metacall_loader_test() { - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } }; @@ -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_call_map_test/CMakeLists.txt b/source/tests/metacall_typescript_call_map_test/CMakeLists.txt index 2d60cbe626..4005debcf6 100644 --- a/source/tests/metacall_typescript_call_map_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_call_map_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -122,6 +131,7 @@ target_link_libraries(${target} add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> + WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) # @@ -139,7 +149,6 @@ add_dependencies(${target} set_property(TEST ${target} PROPERTY LABELS ${target} - WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) include(TestEnvironmentVariables) diff --git a/source/tests/metacall_typescript_call_map_test/source/main.cpp b/source/tests/metacall_typescript_call_map_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_call_map_test/source/main.cpp +++ b/source/tests/metacall_typescript_call_map_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_call_map_test/source/metacall_typescript_call_map_test.cpp b/source/tests/metacall_typescript_call_map_test/source/metacall_typescript_call_map_test.cpp index 923f8e0484..82af7b2944 100644 --- a/source/tests/metacall_typescript_call_map_test/source/metacall_typescript_call_map_test.cpp +++ b/source/tests/metacall_typescript_call_map_test/source/metacall_typescript_call_map_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -79,5 +79,5 @@ TEST_F(metacall_typescript_call_map_test, DefaultConstructor) metacall_allocator_destroy(allocator); - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_jsx_default_test/CMakeLists.txt b/source/tests/metacall_typescript_jsx_default_test/CMakeLists.txt index 3f76973e63..32674e550f 100644 --- a/source/tests/metacall_typescript_jsx_default_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_jsx_default_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_typescript_jsx_default_test/source/main.cpp b/source/tests/metacall_typescript_jsx_default_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_jsx_default_test/source/main.cpp +++ b/source/tests/metacall_typescript_jsx_default_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_jsx_default_test/source/metacall_typescript_jsx_default_test.cpp b/source/tests/metacall_typescript_jsx_default_test/source/metacall_typescript_jsx_default_test.cpp index 7ac88e6da7..609bb760e3 100644 --- a/source/tests/metacall_typescript_jsx_default_test/source/metacall_typescript_jsx_default_test.cpp +++ b/source/tests/metacall_typescript_jsx_default_test/source/metacall_typescript_jsx_default_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -47,5 +47,5 @@ TEST_F(metacall_typescript_jsx_default_test, DefaultConstructor) } #endif /* OPTION_BUILD_LOADERS_TS */ - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_node_test/CMakeLists.txt b/source/tests/metacall_typescript_node_test/CMakeLists.txt index b6347d0497..9dbd14de9d 100644 --- a/source/tests/metacall_typescript_node_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_node_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -122,6 +131,7 @@ target_link_libraries(${target} add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> + WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) # @@ -139,7 +149,6 @@ add_dependencies(${target} set_property(TEST ${target} PROPERTY LABELS ${target} - WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) include(TestEnvironmentVariables) diff --git a/source/tests/metacall_typescript_node_test/source/main.cpp b/source/tests/metacall_typescript_node_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_node_test/source/main.cpp +++ b/source/tests/metacall_typescript_node_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_node_test/source/metacall_typescript_node_test.cpp b/source/tests/metacall_typescript_node_test/source/metacall_typescript_node_test.cpp index 9f51a73c4d..4285ca809f 100644 --- a/source/tests/metacall_typescript_node_test/source/metacall_typescript_node_test.cpp +++ b/source/tests/metacall_typescript_node_test/source/metacall_typescript_node_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -138,5 +138,5 @@ TEST_F(metacall_typescript_node_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_require_test/CMakeLists.txt b/source/tests/metacall_typescript_require_test/CMakeLists.txt index 48af41357c..d4d51e4660 100644 --- a/source/tests/metacall_typescript_require_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_require_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -122,6 +131,7 @@ target_link_libraries(${target} add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> + WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) # @@ -139,7 +149,6 @@ add_dependencies(${target} set_property(TEST ${target} PROPERTY LABELS ${target} - WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) include(TestEnvironmentVariables) diff --git a/source/tests/metacall_typescript_require_test/source/main.cpp b/source/tests/metacall_typescript_require_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_require_test/source/main.cpp +++ b/source/tests/metacall_typescript_require_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_require_test/source/metacall_typescript_require_test.cpp b/source/tests/metacall_typescript_require_test/source/metacall_typescript_require_test.cpp index 8ec87717f8..b94e43fa36 100644 --- a/source/tests/metacall_typescript_require_test/source/metacall_typescript_require_test.cpp +++ b/source/tests/metacall_typescript_require_test/source/metacall_typescript_require_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -77,5 +77,5 @@ TEST_F(metacall_typescript_require_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_test/CMakeLists.txt b/source/tests/metacall_typescript_test/CMakeLists.txt index 73b56edcd6..9af3378ebb 100644 --- a/source/tests/metacall_typescript_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) @@ -122,6 +131,7 @@ target_link_libraries(${target} add_test(NAME ${target} COMMAND $<TARGET_FILE:${target}> + WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) # @@ -139,7 +149,6 @@ add_dependencies(${target} set_property(TEST ${target} PROPERTY LABELS ${target} - WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc ) include(TestEnvironmentVariables) diff --git a/source/tests/metacall_typescript_test/source/main.cpp b/source/tests/metacall_typescript_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_test/source/main.cpp +++ b/source/tests/metacall_typescript_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_test/source/metacall_typescript_test.cpp b/source/tests/metacall_typescript_test/source/metacall_typescript_test.cpp index 60d1868219..9ebd5f9f30 100644 --- a/source/tests/metacall_typescript_test/source/metacall_typescript_test.cpp +++ b/source/tests/metacall_typescript_test/source/metacall_typescript_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -126,5 +126,5 @@ TEST_F(metacall_typescript_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_tsx_loop_fail_test/CMakeLists.txt b/source/tests/metacall_typescript_tsx_loop_fail_test/CMakeLists.txt index 0eab47ceb2..ca6465387a 100644 --- a/source/tests/metacall_typescript_tsx_loop_fail_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_tsx_loop_fail_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_typescript_tsx_loop_fail_test/source/main.cpp b/source/tests/metacall_typescript_tsx_loop_fail_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_tsx_loop_fail_test/source/main.cpp +++ b/source/tests/metacall_typescript_tsx_loop_fail_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_typescript_tsx_loop_fail_test/source/metacall_typescript_tsx_loop_fail_test.cpp b/source/tests/metacall_typescript_tsx_loop_fail_test/source/metacall_typescript_tsx_loop_fail_test.cpp index 1635e15a04..54a278e394 100644 --- a/source/tests/metacall_typescript_tsx_loop_fail_test/source/metacall_typescript_tsx_loop_fail_test.cpp +++ b/source/tests/metacall_typescript_tsx_loop_fail_test/source/metacall_typescript_tsx_loop_fail_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -68,5 +68,5 @@ TEST_F(metacall_tsx_loop_fail_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_typescript_tsx_test/CMakeLists.txt b/source/tests/metacall_typescript_tsx_test/CMakeLists.txt index 2be3b225b2..53682fa434 100644 --- a/source/tests/metacall_typescript_tsx_test/CMakeLists.txt +++ b/source/tests/metacall_typescript_tsx_test/CMakeLists.txt @@ -107,11 +107,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_typescript_tsx_test/source/main.cpp b/source/tests/metacall_typescript_tsx_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_typescript_tsx_test/source/main.cpp +++ b/source/tests/metacall_typescript_tsx_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 82a9dc0c6c..52a406737c 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 @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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); } @@ -79,5 +79,5 @@ TEST_F(metacall_tsx_test, DefaultConstructor) metacall_allocator_destroy(allocator); } - EXPECT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/metacall_version_test/CMakeLists.txt b/source/tests/metacall_version_test/CMakeLists.txt index f519f674ed..4d93e4fec3 100644 --- a/source/tests/metacall_version_test/CMakeLists.txt +++ b/source/tests/metacall_version_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_version_test/source/main.cpp b/source/tests/metacall_version_test/source/main.cpp index 11ddf3f599..5820341294 100644 --- a/source/tests/metacall_version_test/source/main.cpp +++ b/source/tests/metacall_version_test/source/main.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 531e7bdd5f..ef703c79a3 100644 --- a/source/tests/metacall_version_test/source/metacall_version_test.cpp +++ b/source/tests/metacall_version_test/source/metacall_version_test.cpp @@ -2,7 +2,7 @@ * MetaCall Library by Parra Studios * A library for providing a foreign function interface calls. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/metacall_wasm_python_port_test/CMakeLists.txt b/source/tests/metacall_wasm_python_port_test/CMakeLists.txt index 9887521702..7233aa5796 100644 --- a/source/tests/metacall_wasm_python_port_test/CMakeLists.txt +++ b/source/tests/metacall_wasm_python_port_test/CMakeLists.txt @@ -108,11 +108,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_wasm_python_port_test/source/main.cpp b/source/tests/metacall_wasm_python_port_test/source/main.cpp index 31f757ddc4..ae1380d351 100644 --- a/source/tests/metacall_wasm_python_port_test/source/main.cpp +++ b/source/tests/metacall_wasm_python_port_test/source/main.cpp @@ -1,7 +1,7 @@ /* * WebAssembly Loader Tests by Parra Studios * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_wasm_python_port_test/source/metacall_wasm_python_port_test.cpp b/source/tests/metacall_wasm_python_port_test/source/metacall_wasm_python_port_test.cpp index 7896135fe3..f233b6a52c 100644 --- a/source/tests/metacall_wasm_python_port_test/source/metacall_wasm_python_port_test.cpp +++ b/source/tests/metacall_wasm_python_port_test/source/metacall_wasm_python_port_test.cpp @@ -1,7 +1,7 @@ /* * WebAssembly Loader Tests by Parra Studios * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_wasm_test/CMakeLists.txt b/source/tests/metacall_wasm_test/CMakeLists.txt index 2d1d0b0f3e..6ceca66927 100644 --- a/source/tests/metacall_wasm_test/CMakeLists.txt +++ b/source/tests/metacall_wasm_test/CMakeLists.txt @@ -106,11 +106,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/metacall_wasm_test/source/main.cpp b/source/tests/metacall_wasm_test/source/main.cpp index 31f757ddc4..ae1380d351 100644 --- a/source/tests/metacall_wasm_test/source/main.cpp +++ b/source/tests/metacall_wasm_test/source/main.cpp @@ -1,7 +1,7 @@ /* * WebAssembly Loader Tests by Parra Studios * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp b/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp index eb49b144c3..0042e45b7c 100644 --- a/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp +++ b/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp @@ -1,7 +1,7 @@ /* * WebAssembly Loader Tests by Parra Studios * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -192,5 +192,5 @@ TEST_F(metacall_wasm_test, Default) ASSERT_EQ((int)1, (int)metacall_load_from_file("wasm", modules, sizeof(modules) / sizeof(modules[0]), NULL)); } - ASSERT_EQ((int)0, (int)metacall_destroy()); + metacall_destroy(); } diff --git a/source/tests/portability_path_test/CMakeLists.txt b/source/tests/portability_path_test/CMakeLists.txt index bc736b07de..b95e327189 100644 --- a/source/tests/portability_path_test/CMakeLists.txt +++ b/source/tests/portability_path_test/CMakeLists.txt @@ -101,11 +101,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/portability_path_test/source/main.cpp b/source/tests/portability_path_test/source/main.cpp index 1888b3214a..24fae6af69 100644 --- a/source/tests/portability_path_test/source/main.cpp +++ b/source/tests/portability_path_test/source/main.cpp @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 f497563480..f4c638c2f0 100644 --- a/source/tests/portability_path_test/source/portability_path_test.cpp +++ b/source/tests/portability_path_test/source/portability_path_test.cpp @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios -* Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +* Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A library for loading executable code at run-time into a process. * @@ -33,7 +33,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_module_name) size_t size = portability_path_get_module_name(base, sizeof(base), extension, sizeof(extension), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -48,7 +48,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_module_name_without size_t size = portability_path_get_module_name(base, sizeof(base), extension, sizeof(extension), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -63,7 +63,34 @@ TEST_F(portability_path_test, portability_path_test_path_get_module_name_with_ra size_t size = portability_path_get_module_name(base, sizeof(base), extension, sizeof(extension), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + 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_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]); } @@ -77,7 +104,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -91,7 +118,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_end_dot) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -105,7 +132,49 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_without_dot) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + 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) +{ + 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[] = "/."; + 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]); } @@ -119,7 +188,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_only_dot) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -133,7 +202,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_two_dots) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -147,7 +216,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_three_dots) size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -161,7 +230,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_only_extension size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -175,7 +244,7 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_double_extensi size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + EXPECT_STREQ(name, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -189,7 +258,21 @@ TEST_F(portability_path_test, portability_path_test_path_get_name_triple_extensi size_t size = portability_path_get_name(base, sizeof(base), name, NAME_SIZE); - EXPECT_EQ((int)0, (int)strcmp(name, result)); + 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_nullchar) +{ + static const char base[] = "/home/yeet/.nvm/versions/node/v18.20.3/bin/node"; + static const char result[] = "node"; + + 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]); } @@ -203,7 +286,7 @@ TEST_F(portability_path_test, portability_path_test_get_path_of_path) size_t size = portability_path_get_directory(base, sizeof(base), path, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(path, result)); + EXPECT_STREQ(path, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -217,7 +300,7 @@ TEST_F(portability_path_test, portability_path_test_get_path_of_filepath) size_t size = portability_path_get_directory(base, sizeof(base), path, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(path, result)); + EXPECT_STREQ(path, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -232,7 +315,7 @@ TEST_F(portability_path_test, portability_path_test_get_relative) size_t size = portability_path_get_relative(base, sizeof(base), path, sizeof(path), relative, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(relative, result)); + EXPECT_STREQ(relative, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -247,7 +330,7 @@ TEST_F(portability_path_test, portability_path_test_get_relative_fail) size_t size = portability_path_get_relative(base, sizeof(base), path, sizeof(path), relative, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(relative, result)); + EXPECT_STREQ(relative, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -262,7 +345,7 @@ TEST_F(portability_path_test, portability_path_test_join_none_slash) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -277,7 +360,7 @@ TEST_F(portability_path_test, portability_path_test_join_left_slash) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -292,7 +375,7 @@ TEST_F(portability_path_test, portability_path_test_join_right_slash) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -307,7 +390,7 @@ TEST_F(portability_path_test, portability_path_test_join_both_slash) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -322,7 +405,7 @@ TEST_F(portability_path_test, portability_path_test_join_left_empty) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -337,7 +420,7 @@ TEST_F(portability_path_test, portability_path_test_join_right_empty) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -352,7 +435,7 @@ TEST_F(portability_path_test, portability_path_test_join_right_empty_non_slash) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -367,7 +450,7 @@ TEST_F(portability_path_test, portability_path_test_join_both_empty) size_t size = portability_path_join(left, sizeof(left), right, sizeof(right), join, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(join, result)); + EXPECT_STREQ(join, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -381,7 +464,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -395,7 +478,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_double_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -409,7 +492,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_many_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -423,7 +506,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_many_double_ size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -437,7 +520,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_dot_non_slas size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -451,7 +534,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_many_dot_non size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -465,7 +548,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_begin_invalid) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -479,7 +562,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_middle_double_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -493,7 +576,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_middle_double_dot_ size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -507,7 +590,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_middle_double_dot_ size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -521,7 +604,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_middle_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -535,7 +618,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_middle_mixed_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -549,7 +632,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_end_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -563,7 +646,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_end_double_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -577,7 +660,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_end_mixed_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -591,7 +674,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_absolute_end_mixed size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -605,7 +688,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_absolute_end_dot) size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -619,7 +702,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_relative_begin_end size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } @@ -633,7 +716,7 @@ TEST_F(portability_path_test, portability_path_test_canonical_absolute_end_many_ size_t size = portability_path_canonical(path, sizeof(path), canonical, PATH_SIZE); - EXPECT_EQ((int)0, (int)strcmp(canonical, result)); + EXPECT_STREQ(canonical, result); EXPECT_EQ((size_t)size, (size_t)sizeof(result)); EXPECT_EQ((char)'\0', (char)result[size - 1]); } diff --git a/source/tests/preprocessor_test/CMakeLists.txt b/source/tests/preprocessor_test/CMakeLists.txt index f6533c008a..b96a639036 100644 --- a/source/tests/preprocessor_test/CMakeLists.txt +++ b/source/tests/preprocessor_test/CMakeLists.txt @@ -102,11 +102,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/preprocessor_test/source/main.cpp b/source/tests/preprocessor_test/source/main.cpp index d678d80ae7..ccd0ee35a6 100644 --- a/source/tests/preprocessor_test/source/main.cpp +++ b/source/tests/preprocessor_test/source/main.cpp @@ -2,7 +2,7 @@ * Logger Library by Parra Studios * A generic logger library providing application execution reports. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/preprocessor_test/source/preprocessor_test.cpp b/source/tests/preprocessor_test/source/preprocessor_test.cpp index 1c5bf3e610..4e406c3849 100644 --- a/source/tests/preprocessor_test/source/preprocessor_test.cpp +++ b/source/tests/preprocessor_test/source/preprocessor_test.cpp @@ -2,7 +2,7 @@ * Preprocssor Library by Parra Studios * A generic header-only preprocessor metaprogramming library. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -179,6 +179,46 @@ TEST_F(preprocessor_test, if) EXPECT_NE((int)0, PREPROCESSOR_IF(0, (int)0, (int)1)); } +TEST_F(preprocessor_test, if_va_args) +{ +#define PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C, ...) \ + PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), 1, 0) + + EXPECT_EQ((int)1, (int)PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C)); + EXPECT_EQ((int)0, (int)PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C, D)); + EXPECT_EQ((int)0, (int)PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C, D, E)); + EXPECT_EQ((int)0, (int)PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C, D, E, F)); + +#undef PREPROCESSOR_TEST_IF_VA_ARGS +} + +TEST_F(preprocessor_test, if_va_args_ext) +{ +#define PREPROCESSOR_TEST_IF_VA_ARGS_PRINT(A, B, C) \ + do \ + { \ + printf("%d %d %d\n", A, B, C); \ + } while (0) + +#define PREPROCESSOR_TEST_IF_VA_ARGS_PRINT_VA(A, B, C, ...) \ + do \ + { \ + printf(A, B, C, __VA_ARGS__); \ + } while (0) + +#define PREPROCESSOR_TEST_IF_VA_ARGS(A, B, C, ...) \ + PREPROCESSOR_IF(PREPROCESSOR_ARGS_EMPTY(__VA_ARGS__), \ + PREPROCESSOR_TEST_IF_VA_ARGS_PRINT(A, B, C), \ + PREPROCESSOR_TEST_IF_VA_ARGS_PRINT_VA(A, B, C, __VA_ARGS__)) + + PREPROCESSOR_TEST_IF_VA_ARGS(1, 2, 3); + PREPROCESSOR_TEST_IF_VA_ARGS("%s %s %s\n", "B", "C", "D"); + PREPROCESSOR_TEST_IF_VA_ARGS("%s %s %s %s\n", "B", "C", "D", "E"); + PREPROCESSOR_TEST_IF_VA_ARGS("%s %s %s %s %s\n", "B", "C", "D", "E", "F"); + +#undef PREPROCESSOR_TEST_IF_VA_ARGS +} + TEST_F(preprocessor_test, serial) { #define PREPROCSSOR_TEST_SERIAL_TAG abc diff --git a/source/tests/rb_loader_parser_test/CMakeLists.txt b/source/tests/rb_loader_parser_test/CMakeLists.txt index 3242839e25..af3df47fee 100644 --- a/source/tests/rb_loader_parser_test/CMakeLists.txt +++ b/source/tests/rb_loader_parser_test/CMakeLists.txt @@ -79,6 +79,7 @@ target_include_directories(${target} ${PROJECT_BINARY_DIR}/source/include # Ruby Loader headers + ${CMAKE_BINARY_DIR}/source/loaders/rb_loader/include ${CMAKE_SOURCE_DIR}/source/loaders/rb_loader/include ) @@ -121,11 +122,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/rb_loader_parser_test/source/main.cpp b/source/tests/rb_loader_parser_test/source/main.cpp index 4537c68d36..37d4adc23f 100644 --- a/source/tests/rb_loader_parser_test/source/main.cpp +++ b/source/tests/rb_loader_parser_test/source/main.cpp @@ -2,7 +2,7 @@ * Loader Library by Parra Studios * A plugin for loading ruby code at run-time into a process. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/rb_loader_parser_test/source/rb_loader_parser_test.cpp b/source/tests/rb_loader_parser_test/source/rb_loader_parser_test.cpp index 98066bc985..a8984ff47f 100644 --- a/source/tests/rb_loader_parser_test/source/rb_loader_parser_test.cpp +++ b/source/tests/rb_loader_parser_test/source/rb_loader_parser_test.cpp @@ -1,6 +1,6 @@ /* * Loader Library by Parra Studios - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> * * A plugin for loading ruby code at run-time into a process. * diff --git a/source/tests/reflect_function_test/CMakeLists.txt b/source/tests/reflect_function_test/CMakeLists.txt index 3a7ae3a808..fd1875cd36 100644 --- a/source/tests/reflect_function_test/CMakeLists.txt +++ b/source/tests/reflect_function_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/reflect_function_test/source/main.cpp b/source/tests/reflect_function_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/reflect_function_test/source/main.cpp +++ b/source/tests/reflect_function_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_function_test/source/reflect_function_test.cpp b/source/tests/reflect_function_test/source/reflect_function_test.cpp index eea9349278..7567f4505c 100644 --- a/source/tests/reflect_function_test/source/reflect_function_test.cpp +++ b/source/tests/reflect_function_test/source/reflect_function_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_metadata_test/CMakeLists.txt b/source/tests/reflect_metadata_test/CMakeLists.txt index 375080bea7..33497b513c 100644 --- a/source/tests/reflect_metadata_test/CMakeLists.txt +++ b/source/tests/reflect_metadata_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/reflect_metadata_test/source/main.cpp b/source/tests/reflect_metadata_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/reflect_metadata_test/source/main.cpp +++ b/source/tests/reflect_metadata_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_metadata_test/source/reflect_metadata_test.cpp b/source/tests/reflect_metadata_test/source/reflect_metadata_test.cpp index 32747c825f..6c1bc10f7a 100644 --- a/source/tests/reflect_metadata_test/source/reflect_metadata_test.cpp +++ b/source/tests/reflect_metadata_test/source/reflect_metadata_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_object_class_test/CMakeLists.txt b/source/tests/reflect_object_class_test/CMakeLists.txt index 6b515aec62..3a74590dc5 100644 --- a/source/tests/reflect_object_class_test/CMakeLists.txt +++ b/source/tests/reflect_object_class_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/reflect_object_class_test/source/main.cpp b/source/tests/reflect_object_class_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/reflect_object_class_test/source/main.cpp +++ b/source/tests/reflect_object_class_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. 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 275713e5fe..1abd68347d 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 @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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/reflect_scope_test/CMakeLists.txt b/source/tests/reflect_scope_test/CMakeLists.txt index ba08a0cd72..83990f2359 100644 --- a/source/tests/reflect_scope_test/CMakeLists.txt +++ b/source/tests/reflect_scope_test/CMakeLists.txt @@ -115,11 +115,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/reflect_scope_test/source/main.cpp b/source/tests/reflect_scope_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/reflect_scope_test/source/main.cpp +++ b/source/tests/reflect_scope_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_scope_test/source/reflect_scope_test.cpp b/source/tests/reflect_scope_test/source/reflect_scope_test.cpp index 5287159253..2e58c50b04 100644 --- a/source/tests/reflect_scope_test/source/reflect_scope_test.cpp +++ b/source/tests/reflect_scope_test/source/reflect_scope_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/CMakeLists.txt b/source/tests/reflect_value_cast_test/CMakeLists.txt index aa40caae6f..4b28d3a1a9 100644 --- a/source/tests/reflect_value_cast_test/CMakeLists.txt +++ b/source/tests/reflect_value_cast_test/CMakeLists.txt @@ -121,11 +121,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/reflect_value_cast_test/source/main.cpp b/source/tests/reflect_value_cast_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/reflect_value_cast_test/source/main.cpp +++ b/source/tests/reflect_value_cast_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_bool_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_bool_test.cpp index 49770adaf8..988e7a607a 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_bool_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_bool_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_char_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_char_test.cpp index 35d20ad945..0bbe2bbecf 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_char_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_char_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_double_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_double_test.cpp index 7d7fad6cbb..8991352731 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_double_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_double_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_float_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_float_test.cpp index 8c543a3815..f1ffedc062 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_float_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_float_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_int_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_int_test.cpp index 9d5a67abbf..7e6e2aa35d 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_int_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_int_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_long_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_long_test.cpp index fa5ea251a5..9258a11e32 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_long_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_long_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/reflect_value_cast_test/source/reflect_value_cast_short_test.cpp b/source/tests/reflect_value_cast_test/source/reflect_value_cast_short_test.cpp index 48211f3cbc..e33d576373 100644 --- a/source/tests/reflect_value_cast_test/source/reflect_value_cast_short_test.cpp +++ b/source/tests/reflect_value_cast_test/source/reflect_value_cast_short_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/serial_test/CMakeLists.txt b/source/tests/serial_test/CMakeLists.txt index 2cf1c6bcef..12356bc112 100644 --- a/source/tests/serial_test/CMakeLists.txt +++ b/source/tests/serial_test/CMakeLists.txt @@ -120,11 +120,20 @@ target_compile_options(${target} ${DEFAULT_COMPILE_OPTIONS} ) +# +# Compile features +# + +target_compile_features(${target} + PRIVATE + cxx_std_17 +) + # # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE ${DEFAULT_LINKER_OPTIONS} ) diff --git a/source/tests/serial_test/source/main.cpp b/source/tests/serial_test/source/main.cpp index 718fa27071..cba58797ca 100644 --- a/source/tests/serial_test/source/main.cpp +++ b/source/tests/serial_test/source/main.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/tests/serial_test/source/serial_test.cpp b/source/tests/serial_test/source/serial_test.cpp index c2216a5b8c..bf2d158acb 100644 --- a/source/tests/serial_test/source/serial_test.cpp +++ b/source/tests/serial_test/source/serial_test.cpp @@ -2,7 +2,7 @@ * Reflect Library by Parra Studios * A library for provide reflection and metadata representation. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -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])); diff --git a/source/threading/CMakeLists.txt b/source/threading/CMakeLists.txt index a0109ce8d9..830545d85c 100644 --- a/source/threading/CMakeLists.txt +++ b/source/threading/CMakeLists.txt @@ -178,7 +178,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/threading/include/threading/threading.h b/source/threading/include/threading/threading.h index f79566a1b2..f0b7114816 100644 --- a/source/threading/include/threading/threading.h +++ b/source/threading/include/threading/threading.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/threading/include/threading/threading_atomic.h b/source/threading/include/threading/threading_atomic.h index a2b870d3ae..26ba7c45b3 100644 --- a/source/threading/include/threading/threading_atomic.h +++ b/source/threading/include/threading/threading_atomic.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -31,12 +31,21 @@ extern "C" { /* -- Definitions -- */ -#if defined(__STDC_VERSION__) - #if __STDC_VERSION__ - 0L >= 201112L +#if defined(_WIN32) && defined(_MSC_VER) + #if (_MSC_VER < 1930 || defined(__STDC_NO_ATOMICS__)) + /* Before Visual Studio 2022 atomics are not supported, use fallback solution */ + #include <threading/threading_atomic_win32.h> + #define THREADING_ATOMIC 1 + #else + #include <stdatomic.h> + #define THREADING_ATOMIC 1 + #endif +#elif defined(__STDC_VERSION__) + #if (__STDC_VERSION__ - 0L) >= 201112L /* C11 support */ #if defined(__STDC_NO_ATOMICS__) - /* TODO: C11 atomics not supported, check the platform and implement support if needed */ #define THREADING_ATOMIC 0 + #error "Using C11 but atomics not supported, check the platform and implement support" #elif defined __has_include #if __has_include(<stdatomic.h>) #include <stdatomic.h> @@ -47,17 +56,8 @@ extern "C" { #define THREADING_ATOMIC 1 #endif #else - /* TODO: C11 is not supported, check the platform and implement support if needed */ #define THREADING_ATOMIC 0 - #endif -#elif defined(_WIN32) && defined(_MSC_VER) - #if (_MSC_VER < 1930) - /* Before Visual Studio 2022 atomics are not supported, use fallback solution */ - #include <threading/threading_atomic_win32.h> - #define THREADING_ATOMIC 1 - #else - #include <stdatomic.h> - #define THREADING_ATOMIC 1 + #error "C11 is not supported, check the platform and implement support" #endif #else /* TODO: Unknown compiler and platform, check the platform and compiler, then implement support if needed */ diff --git a/source/threading/include/threading/threading_atomic_ref_count.h b/source/threading/include/threading/threading_atomic_ref_count.h index afdae715bc..8a1dc1cc45 100644 --- a/source/threading/include/threading/threading_atomic_ref_count.h +++ b/source/threading/include/threading/threading_atomic_ref_count.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -46,19 +46,19 @@ extern "C" { /* -- Member Data -- */ -struct threading_atomic_ref_count_type +typedef struct { #if defined(__THREAD_SANITIZER__) uintmax_t count; - struct threading_mutex_type m; + threading_mutex_type m; #else atomic_uintmax_t count; #endif -}; +} threading_atomic_ref_count_type; /* -- Type Definitions -- */ -typedef struct threading_atomic_ref_count_type *threading_atomic_ref_count; +typedef threading_atomic_ref_count_type *threading_atomic_ref_count; /* -- Methods -- */ diff --git a/source/threading/include/threading/threading_atomic_win32.h b/source/threading/include/threading/threading_atomic_win32.h index 0686f9a005..00c2055aa5 100644 --- a/source/threading/include/threading/threading_atomic_win32.h +++ b/source/threading/include/threading/threading_atomic_win32.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/threading/include/threading/threading_mutex.h b/source/threading/include/threading/threading_mutex.h index 174e5772e1..c9b346c3c8 100644 --- a/source/threading/include/threading/threading_mutex.h +++ b/source/threading/include/threading/threading_mutex.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -33,6 +33,10 @@ extern "C" { #if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) #include <windows.h> + #define THREADING_MUTEX_INITIALIZE \ + { \ + 0 \ + } typedef CRITICAL_SECTION threading_mutex_impl_type; #elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux) || defined(__gnu_linux__) || defined(__TOS_LINUX__)) || \ defined(__FreeBSD__) || \ @@ -41,10 +45,12 @@ typedef CRITICAL_SECTION threading_mutex_impl_type; (defined(bsdi) || defined(__bsdi__)) || \ defined(__DragonFly__) #include <pthread.h> + #define THREADING_MUTEX_INITIALIZE PTHREAD_MUTEX_INITIALIZER typedef pthread_mutex_t threading_mutex_impl_type; #elif (defined(__MACOS__) || defined(macintosh) || defined(Macintosh) || defined(__TOS_MACOS__)) || \ (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) #include <os/lock.h> + #define THREADING_MUTEX_INITIALIZE OS_UNFAIR_LOCK_INIT typedef os_unfair_lock threading_mutex_impl_type; #else #error "Platform not supported for mutex implementation" @@ -52,16 +58,10 @@ typedef os_unfair_lock threading_mutex_impl_type; #include <string.h> -/* -- Member Data -- */ - -struct threading_mutex_type -{ - threading_mutex_impl_type impl; -}; - /* -- Type Definitions -- */ -typedef struct threading_mutex_type *threading_mutex; +typedef threading_mutex_impl_type threading_mutex_type; +typedef threading_mutex_type *threading_mutex; /* -- Methods -- */ diff --git a/source/threading/include/threading/threading_thread_id.h b/source/threading/include/threading/threading_thread_id.h index 1545e0faa6..af111a4fe0 100644 --- a/source/threading/include/threading/threading_thread_id.h +++ b/source/threading/include/threading/threading_thread_id.h @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/threading/source/threading.c b/source/threading/source/threading.c index 0d82cd3055..2d795819f0 100644 --- a/source/threading/source/threading.c +++ b/source/threading/source/threading.c @@ -2,7 +2,7 @@ * Thrading Library by Parra Studios * A threading library providing utilities for lock-free data structures and more. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -26,7 +26,7 @@ const char *threading_print_info(void) { static const char threading_info[] = "Threading Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef ADT_STATIC_DEFINE "Compiled as static library type" diff --git a/source/threading/source/threading_mutex_macos.c b/source/threading/source/threading_mutex_macos.c index e8fe440479..ed47663215 100644 --- a/source/threading/source/threading_mutex_macos.c +++ b/source/threading/source/threading_mutex_macos.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -26,21 +26,21 @@ int threading_mutex_initialize(threading_mutex m) { - memset(&m->impl, 0, sizeof(os_unfair_lock)); + memset(m, 0, sizeof(os_unfair_lock)); return 0; } int threading_mutex_lock(threading_mutex m) { - os_unfair_lock_lock(&m->impl); + os_unfair_lock_lock(m); return 0; } int threading_mutex_try_lock(threading_mutex m) { - if (os_unfair_lock_trylock(&m->impl) == false) + if (os_unfair_lock_trylock(m) == false) { return 1; } @@ -50,7 +50,7 @@ int threading_mutex_try_lock(threading_mutex m) int threading_mutex_unlock(threading_mutex m) { - os_unfair_lock_unlock(&m->impl); + os_unfair_lock_unlock(m); return 0; } diff --git a/source/threading/source/threading_mutex_pthread.c b/source/threading/source/threading_mutex_pthread.c index 3a288830e1..4fc161d347 100644 --- a/source/threading/source/threading_mutex_pthread.c +++ b/source/threading/source/threading_mutex_pthread.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -24,25 +24,25 @@ int threading_mutex_initialize(threading_mutex m) { - return pthread_mutex_init(&m->impl, NULL); + return pthread_mutex_init(m, NULL); } int threading_mutex_lock(threading_mutex m) { - return pthread_mutex_lock(&m->impl); + return pthread_mutex_lock(m); } int threading_mutex_try_lock(threading_mutex m) { - return pthread_mutex_trylock(&m->impl); + return pthread_mutex_trylock(m); } int threading_mutex_unlock(threading_mutex m) { - return pthread_mutex_unlock(&m->impl); + return pthread_mutex_unlock(m); } int threading_mutex_destroy(threading_mutex m) { - return pthread_mutex_destroy(&m->impl); + return pthread_mutex_destroy(m); } diff --git a/source/threading/source/threading_mutex_win32.c b/source/threading/source/threading_mutex_win32.c index 16739c50d9..aefdcfb1e1 100644 --- a/source/threading/source/threading_mutex_win32.c +++ b/source/threading/source/threading_mutex_win32.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -22,25 +22,23 @@ #include <threading/threading_mutex.h> -#include <stdlib.h> - int threading_mutex_initialize(threading_mutex m) { - InitializeCriticalSection(&m->impl); + InitializeCriticalSection(m); return 0; } int threading_mutex_lock(threading_mutex m) { - EnterCriticalSection(&m->impl); + EnterCriticalSection(m); return 0; } int threading_mutex_try_lock(threading_mutex m) { - if (TryEnterCriticalSection(&m->impl) == 0) + if (TryEnterCriticalSection(m) == 0) { return 1; } @@ -50,14 +48,14 @@ int threading_mutex_try_lock(threading_mutex m) int threading_mutex_unlock(threading_mutex m) { - LeaveCriticalSection(&m->impl); + LeaveCriticalSection(m); return 0; } int threading_mutex_destroy(threading_mutex m) { - DeleteCriticalSection(&m->impl); + DeleteCriticalSection(m); return 0; } diff --git a/source/threading/source/threading_thread_id.c b/source/threading/source/threading_thread_id.c index e3fa8030bd..0edf1db792 100644 --- a/source/threading/source/threading_thread_id.c +++ b/source/threading/source/threading_thread_id.c @@ -2,7 +2,7 @@ * Abstract Data Type Library by Parra Studios * A abstract data type library providing generic containers. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/version/CMakeLists.txt b/source/version/CMakeLists.txt index d62729c680..ff0bed815d 100644 --- a/source/version/CMakeLists.txt +++ b/source/version/CMakeLists.txt @@ -151,7 +151,7 @@ target_compile_options(${target} # Linker options # -target_link_libraries(${target} +target_link_options(${target} PRIVATE PUBLIC diff --git a/source/version/include/version/version.h b/source/version/include/version/version.h index 9c0dbcd3d2..eae5523e89 100644 --- a/source/version/include/version/version.h +++ b/source/version/include/version/version.h @@ -2,7 +2,7 @@ * CMake Versioning Utility by Parra Studios * A template for generating versioning utilities. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/version/include/version/version.h.in b/source/version/include/version/version.h.in index 79a37cfd0f..69341f7b5b 100644 --- a/source/version/include/version/version.h.in +++ b/source/version/include/version/version.h.in @@ -2,7 +2,7 @@ * CMake Versioning Utility by Parra Studios * A template for generating versioning utilities. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. diff --git a/source/version/source/version.c b/source/version/source/version.c index 3dca248314..95cec396c5 100644 --- a/source/version/source/version.c +++ b/source/version/source/version.c @@ -2,7 +2,7 @@ * CMake Versioning Utility by Parra Studios * A template for generating versioning utilities. * - * Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> + * 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. @@ -26,7 +26,7 @@ const char *version_print_info(void) { static const char version_info[] = "Version Library " METACALL_VERSION "\n" - "Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" + "Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>\n" #ifdef ADT_STATIC_DEFINE "Compiled as static library type" diff --git a/tools/cli/Dockerfile b/tools/cli/Dockerfile index ee1eaa9431..0da28539b1 100644 --- a/tools/cli/Dockerfile +++ b/tools/cli/Dockerfile @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -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/deps/Dockerfile b/tools/deps/Dockerfile index aa4ba69fe0..342bef8de3 100644 --- a/tools/deps/Dockerfile +++ b/tools/deps/Dockerfile @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/tools/dev/Dockerfile b/tools/dev/Dockerfile index 022c4703a9..ec35dfde43 100644 --- a/tools/dev/Dockerfile +++ b/tools/dev/Dockerfile @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -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-build.ps1 b/tools/metacall-build.ps1 index 483caa2ed6..ec95a2dd85 100755 --- a/tools/metacall-build.ps1 +++ b/tools/metacall-build.ps1 @@ -2,7 +2,7 @@ # MetaCall Build PowerShell Script by Parra Studios # Build and install powershell script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/tools/metacall-build.sh b/tools/metacall-build.sh index d2074c1afb..74826e22f2 100755 --- a/tools/metacall-build.sh +++ b/tools/metacall-build.sh @@ -4,7 +4,7 @@ # MetaCall Build Shell Script by Parra Studios # Build and install shell script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/tools/metacall-configure.ps1 b/tools/metacall-configure.ps1 index bcfaf74cfc..ea3928e666 100755 --- a/tools/metacall-configure.ps1 +++ b/tools/metacall-configure.ps1 @@ -2,7 +2,7 @@ # MetaCall Build PowerShell Script by Parra Studios # Build and install powershell script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. diff --git a/tools/metacall-configure.sh b/tools/metacall-configure.sh index 206bc1e475..7847a0d347 100755 --- a/tools/metacall-configure.sh +++ b/tools/metacall-configure.sh @@ -4,7 +4,7 @@ # MetaCall Build Shell Script by Parra Studios # Build and install shell script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -29,6 +29,7 @@ BUILD_NETCORE=0 BUILD_NETCORE2=0 BUILD_NETCORE5=0 BUILD_NETCORE7=0 +BUILD_NETCORE8=0 BUILD_V8=0 BUILD_NODEJS=0 BUILD_TYPESCRIPT=0 @@ -112,6 +113,10 @@ sub_options() { echo "Build with netcore 7 support" BUILD_NETCORE7=1 fi + if [ "$option" = 'netcore8' ]; then + echo "Build with netcore 8 support" + BUILD_NETCORE8=1 + fi if [ "$option" = 'v8' ]; then echo "Build with v8 support" BUILD_V8=1 @@ -318,6 +323,21 @@ sub_configure() { fi fi + # NetCore 8 + if [ $BUILD_NETCORE8 = 1 ]; then + BUILD_STRING="$BUILD_STRING \ + -DOPTION_BUILD_LOADERS_CS=On \ + -DDOTNET_CORE_PATH=`sub_find_dotnet_runtime 8`" + + if [ $BUILD_SCRIPTS = 1 ]; then + BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_SCRIPTS_CS=On" + fi + + if [ $BUILD_PORTS = 1 ]; then + BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_PORTS_CS=On" + fi + fi + # V8 if [ $BUILD_V8 = 1 ]; then BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_LOADERS_JS=On" @@ -545,6 +565,7 @@ sub_help() { echo " netcore2: build with netcore 2 support" echo " netcore5: build with netcore 5 support" echo " netcore7: build with netcore 7 support" + echo " netcore8: build with netcore 8 support" echo " v8: build with v8 support" echo " nodejs: build with nodejs support" echo " typescript: build with typescript support" diff --git a/tools/metacall-environment.ps1 b/tools/metacall-environment.ps1 index 1638de22c8..486edf7713 100755 --- a/tools/metacall-environment.ps1 +++ b/tools/metacall-environment.ps1 @@ -2,7 +2,7 @@ # MetaCall Build PowerShell Script by Parra Studios # Build and install powershell script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -126,6 +126,27 @@ function Set-Nodejs { Write-Output "-DNodeJS_EXECUTABLE=""$NodeDir/node.exe""" >> $EnvOpts Write-Output "-DNodeJS_LIBRARY_NAME=""libnode.dll""" >> $EnvOpts Write-Output "-DNodeJS_LIBRARY_NAME_PATH=""$NodeDir/lib/libnode.dll""" >> $EnvOpts + + if ($Arguments -contains "c") { + # Required for test source/tests/metacall_node_port_c_lib_test + if (!(Test-Path -Path "$DepsDir\libgit2")) { + # Clone libgit2 + git clone --depth 1 --branch v1.8.4 https://github.com/libgit2/libgit2 + } + + $InstallDir = "$DepsDir\libgit2\build\dist" + + mkdir "$DepsDir\libgit2\build" + mkdir "$InstallDir" + Set-Location "$DepsDir\libgit2\build" + + cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=OFF -DBUILD_CLI=OFF .. + cmake --build . "-j$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors)" + cmake --install . --prefix "$InstallDir" + + Write-Output "-DLibGit2_LIBRARY=""$InstallDir\lib\git2.lib""" >> $EnvOpts + Write-Output "-DLibGit2_INCLUDE_DIR=""$InstallDir\include""" >> $EnvOpts + } } function Set-Java { @@ -152,7 +173,6 @@ function Set-Java { function Set-Ruby { Write-Output "Install Ruby" - $RUBY_VERSION = "3.1.2" Set-Location $ROOT_DIR $RuntimeDir = "$env:ProgramFiles\ruby" @@ -161,24 +181,25 @@ function Set-Ruby { if (!(Test-Path -Path "$DepsDir\ruby-mswin.7z")) { # Download installer Write-Output "Ruby not found downloading now..." - (New-Object Net.WebClient).DownloadFile("https://github.com/MSP-Greg/ruby-mswin/releases/download/ruby-mswin-builds/Ruby-$RUBY_VERSION-ms.7z", "$DepsDir\ruby-mswin.7z") + (New-Object Net.WebClient).DownloadFile("https://github.com/metacall/ruby-loco/releases/download/ruby-master/ruby-mswin.7z", "$DepsDir\ruby-mswin.7z") } - mkdir "$DepsDir\Ruby31-ms" + mkdir "$DepsDir\ruby-mswin" 7z x "$DepsDir\ruby-mswin.7z" -o"$DepsDir" - robocopy /move /e "$DepsDir\Ruby31-ms\" $RuntimeDir + robocopy /move /e "$DepsDir\ruby-mswin\" $RuntimeDir Add-to-Path "$RuntimeDir\bin" $EnvOpts = "$ROOT_DIR\build\CMakeConfig.txt" $RubyDir = $RuntimeDir.Replace('\', '/') - Write-Output "-DRuby_VERSION_STRING=""$RUBY_VERSION""" >> $EnvOpts - Write-Output "-DRuby_INCLUDE_DIR=""$RubyDir/include/ruby-3.1.0""" >> $EnvOpts + Write-Output "-DRuby_VERSION_STRING=""3.5.0""" >> $EnvOpts + Write-Output "-DRuby_INCLUDE_DIR=""$RubyDir/include/ruby-3.5.0+0""" >> $EnvOpts Write-Output "-DRuby_EXECUTABLE=""$RubyDir/bin/ruby.exe""" >> $EnvOpts - Write-Output "-DRuby_LIBRARY=""$RubyDir/lib/x64-vcruntime140-ruby310.lib""" >> $EnvOpts - Write-Output "-DRuby_LIBRARY_NAME=""$RubyDir/bin/x64-vcruntime140-ruby310.dll""" >> $EnvOpts + Write-Output "-DRuby_LIBRARY=""$RubyDir/lib/x64-vcruntime140-ruby350.lib""" >> $EnvOpts + Write-Output "-DRuby_LIBRARY_NAME=""$RubyDir/bin/x64-vcruntime140-ruby350.dll""" >> $EnvOpts + Write-Output "-DRuby_LIBRARY_SEARCH_PATHS=""$RubyDir/bin/ruby_builtin_dlls""" >> $EnvOpts } function Set-TypeScript { @@ -289,9 +310,6 @@ function Configure { if ("$var" -eq 'rapidjson') { Write-Output "rapidjson selected" } - if ("$var" -eq 'funchook') { - Write-Output "funchook selected" - } if (("$var" -eq 'v8') -or ("$var" -eq 'v8rep54')) { Write-Output "v8 selected" } @@ -341,9 +359,6 @@ function Configure { if ("$var" -eq 'rust') { Write-Output "rust selected" } - if ("$var" -eq 'swig') { - Write-Output "swig selected" - } if ("$var" -eq 'metacall') { Write-Output "metacall selected" } @@ -366,7 +381,6 @@ function Help { Write-Output " netcore2" Write-Output " netcore5" Write-Output " rapidjson" - Write-Output " funchook" Write-Output " v8" Write-Output " v8rep51" Write-Output " v8rep54" @@ -381,7 +395,6 @@ function Help { Write-Output " c" Write-Output " cobol" Write-Output " go" - Write-Output " swig" Write-Output " metacall" Write-Output " pack" Write-Output " clangformat" diff --git a/tools/metacall-environment.sh b/tools/metacall-environment.sh index 304fa6a02d..577889af99 100755 --- a/tools/metacall-environment.sh +++ b/tools/metacall-environment.sh @@ -4,7 +4,7 @@ # MetaCall Configuration Environment Shell Script by Parra Studios # Configure and install MetaCall environment script utility. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -30,11 +30,11 @@ INSTALL_BASE=1 INSTALL_PYTHON=0 INSTALL_RUBY=0 INSTALL_RAPIDJSON=0 -INSTALL_FUNCHOOK=0 INSTALL_NETCORE=0 INSTALL_NETCORE2=0 INSTALL_NETCORE5=0 INSTALL_NETCORE7=0 +INSTALL_NETCORE8=0 INSTALL_V8=0 INSTALL_V8REPO=0 INSTALL_V8REPO58=0 @@ -52,7 +52,6 @@ INSTALL_C=0 INSTALL_COBOL=0 INSTALL_GO=0 INSTALL_RUST=0 -INSTALL_SWIG=0 INSTALL_PACK=0 INSTALL_COVERAGE=0 INSTALL_CLANGFORMAT=0 @@ -70,6 +69,13 @@ case "$(uname -s)" in *) OPERATIVE_SYSTEM="Unknown" esac +# Architecture detection +case "$(uname -m)" in + x86_64) ARCHITECTURE="amd64";; + arm64) ARCHITECTURE="arm64";; + *) ARCHITECTURE="Unknown";; +esac + # Check out for sudo if [ "`id -u`" = '0' ]; then SUDO_CMD="" @@ -97,35 +103,13 @@ sub_base(){ if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then if [ "${LINUX_DISTRO}" = "debian" ] || [ "${LINUX_DISTRO}" = "ubuntu" ]; then $SUDO_CMD apt-get update - $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends build-essential git cmake libgtest-dev wget apt-utils apt-transport-https gnupg dirmngr ca-certificates + $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends build-essential git cmake wget apt-utils apt-transport-https gnupg dirmngr ca-certificates elif [ "${LINUX_DISTRO}" = "alpine" ]; then $SUDO_CMD apk update - $SUDO_CMD apk add --no-cache g++ make git cmake gtest-dev wget gnupg ca-certificates - fi - elif [ "${OPERATIVE_SYSTEM}" = "Darwin" ]; then - brew install llvm cmake git googletest wget gnupg ca-certificates - fi -} - -# Swig -sub_swig(){ - echo "configure swig" - cd $ROOT_DIR - - if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then - if [ "${LINUX_DISTRO}" = "debian" ] || [ "${LINUX_DISTRO}" = "ubuntu" ]; then - $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends swig - - # Install Python Port Dependencies (TODO: This must be transformed into pip3 install metacall) - $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends python3-setuptools - elif [ "${LINUX_DISTRO}" = "alpine" ]; then - $SUDO_CMD apk add --no-cache swig - - # Install Python Port Dependencies (TODO: This must be transformed into pip3 install metacall) - $SUDO_CMD apk add --no-cache py3-setuptools + $SUDO_CMD apk add --no-cache g++ make git cmake wget gnupg ca-certificates fi elif [ "${OPERATIVE_SYSTEM}" = "Darwin" ]; then - brew install swig + brew install llvm cmake git wget gnupg ca-certificates fi } @@ -243,9 +227,9 @@ sub_rapidjson(){ cd $ROOT_DIR if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then - git clone https://github.com/miloyip/rapidjson.git + git clone https://github.com/Tencent/rapidjson.git cd rapidjson - git checkout ab1842a2dae061284c0a62dca1cc6d5e7e37e346 + git checkout 24b5e7a8b27f42fa16b96fc70aade9106cf7102f mkdir build cd build cmake -DRAPIDJSON_BUILD_DOC=Off -DRAPIDJSON_BUILD_EXAMPLES=Off -DRAPIDJSON_BUILD_TESTS=Off .. @@ -255,12 +239,6 @@ sub_rapidjson(){ fi } -# FuncHook -sub_funchook(){ - echo "configure funchook" - -} - # NetCore sub_netcore(){ echo "configure netcore" @@ -387,6 +365,20 @@ sub_netcore7(){ fi } +# NetCore 8 +sub_netcore8(){ + echo "configure netcore 8" + cd $ROOT_DIR + + if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then + if [ "${LINUX_DISTRO}" = "debian" ] || [ "${LINUX_DISTRO}" = "ubuntu" ]; then + wget -O - https://dot.net/v1/dotnet-install.sh | $SUDO_CMD bash -s -- --version 8.0.408 --install-dir /usr/local/bin + elif [ "${LINUX_DISTRO}" = "alpine" ]; then + $SUDO_CMD apk add --no-cache dotnet8-sdk + fi + fi +} + # V8 Repository sub_v8repo(){ echo "configure v8 from repository" @@ -464,11 +456,18 @@ sub_nodejs(){ cd $ROOT_DIR if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then + if [ $INSTALL_C = 1 ]; then + # Required for test source/tests/metacall_node_port_c_lib_test + INSTALL_LIBGIT2="libgit2-dev" + else + INSTALL_LIBGIT2="" + fi + if [ "${LINUX_DISTRO}" = "debian" ] || [ "${LINUX_DISTRO}" = "ubuntu" ]; then # Note that Python is required for GYP - $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends python3 g++ make nodejs npm curl + $SUDO_CMD apt-get $APT_CACHE_CMD install -y --no-install-recommends python3 g++ make nodejs npm curl $INSTALL_LIBGIT2 elif [ "${LINUX_DISTRO}" = "alpine" ]; then - $SUDO_CMD apk add --no-cache python3 g++ make nodejs nodejs-dev npm curl + $SUDO_CMD apk add --no-cache python3 g++ make nodejs nodejs-dev npm curl $INSTALL_LIBGIT2 # Build dependencies (note libexecinfo-dev is not available in Alpine 3.17) $SUDO_CMD apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/v3.16/main linux-headers libexecinfo libexecinfo-dev @@ -513,30 +512,7 @@ sub_nodejs(){ $SUDO_CMD apk del .build-nodejs-python-deps fi elif [ "${OPERATIVE_SYSTEM}" = "Darwin" ]; then - # TODO: Fork https://github.com/puerts/backend-nodejs or let metacall build system compile NodeJS library itself - # if [ -z "${NodeJS_BUILD_FROM_SOURCE:-}" ]; then - # # Define node location - # NODE_PREFIX="$ROOT_DIR/build" - # # Include binaries into PATH - # export PATH="$NODE_PREFIX:$PATH" - - # # Create install path - # mkdir -p "$NODE_PREFIX" - # # Install NodeJS (TODO: Implement arm64 or amd64 detection into ${arch}) - # wget -qO- https://github.com/metacall/libnode/releases/download/v22.6.0/libnode-${arch}-macos.tar.xz | tar xvJ -C $NODE_PREFIX - # # Install NPM - # wget -qO- https://registry.npmjs.org/npm/-/npm-10.8.2.tgz | tar xvz -C $NODE_PREFIX - - # # Configure NodeJS paths - # mkdir -p "$ROOT_DIR/build" - # CMAKE_CONFIG_PATH="$ROOT_DIR/build/CMakeConfig.txt" - # echo "-DNodeJS_EXECUTABLE=$NODE_PREFIX/node" >> $CMAKE_CONFIG_PATH - # echo "-DNodeJS_LIBRARY=$NODE_PREFIX/libnode.127.dylib" >> $CMAKE_CONFIG_PATH - - # # Configure NPM path - # echo "-DNPM_ROOT=$NODE_PREFIX" >> $CMAKE_CONFIG_PATH - # else - + # Install NodeJS (required for source build or NPM itself) brew install node@22 # Make node 22 the default brew link node@22 --force --overwrite @@ -544,20 +520,38 @@ sub_nodejs(){ brew postinstall node@22 # Define node location NODE_PREFIX=$(brew --prefix node@22) - # Include binaries into PATH - export PATH="$NODE_PREFIX/bin:$PATH" # Configure NodeJS paths mkdir -p "$ROOT_DIR/build" CMAKE_CONFIG_PATH="$ROOT_DIR/build/CMakeConfig.txt" - echo "-DNodeJS_EXECUTABLE=$NODE_PREFIX/bin/node" >> $CMAKE_CONFIG_PATH - # echo "-DNodeJS_INCLUDE_DIR=$NODE_PREFIX/include/node" >> $CMAKE_CONFIG_PATH - # echo "-DNodeJS_LIBRARY=$NODE_PREFIX/lib/libnode.93.dylib" >> $CMAKE_CONFIG_PATH # Configure NPM path echo "-DNPM_ROOT=$NODE_PREFIX/bin" >> $CMAKE_CONFIG_PATH - # fi + # Make npm available for subsequent calls + export PATH="$NODE_PREFIX/bin:$PATH" + + # Build either using pre-compiled binaries or building node from source + if [ -z "${NodeJS_BUILD_FROM_SOURCE:-}" ]; then + # Define node location + NODE_PREFIX="$ROOT_DIR/build" + # Install NodeJS + wget -qO- https://github.com/metacall/libnode/releases/download/v22.9.0/libnode-${ARCHITECTURE}-macos.tar.xz | tar xvJ -C $NODE_PREFIX + # Configure NodeJS path + echo "-DNodeJS_EXECUTABLE=$NODE_PREFIX/node" >> $CMAKE_CONFIG_PATH + echo "-DNodeJS_LIBRARY=$NODE_PREFIX/libnode.dylib" >> $CMAKE_CONFIG_PATH + else + # Include binaries into PATH + export PATH="$NODE_PREFIX/bin:$PATH" + # Define executable path + echo "-DNodeJS_EXECUTABLE=$NODE_PREFIX/bin/node" >> $CMAKE_CONFIG_PATH + fi + + if [ $INSTALL_C = 1 ]; then + # Required for test source/tests/metacall_node_port_c_lib_test + brew install libgit2@1.8 + brew link libgit2@1.8 --force --overwrite + fi fi } @@ -637,10 +631,10 @@ sub_java(){ # C sub_c(){ echo "configure c" + cd $ROOT_DIR + LLVM_VERSION_STRING=14 if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then - LLVM_VERSION_STRING=14 - if [ "${LINUX_DISTRO}" = "debian" ]; then UBUNTU_CODENAME="" CODENAME_FROM_ARGUMENTS="" @@ -680,7 +674,6 @@ sub_c(){ $SUDO_CMD apt-get install -y --no-install-recommends libffi-dev libclang-${LLVM_VERSION_STRING}-dev elif [ "${LINUX_DISTRO}" = "alpine" ]; then $SUDO_CMD apk add --no-cache libffi-dev - $SUDO_CMD apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing tcc $SUDO_CMD apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/v3.16/main clang-libs=13.0.1-r1 clang-dev=13.0.1-r1 fi elif [ "${OPERATIVE_SYSTEM}" = "Darwin" ]; then @@ -912,9 +905,6 @@ sub_install(){ if [ $INSTALL_RAPIDJSON = 1 ]; then sub_rapidjson fi - if [ $INSTALL_FUNCHOOK = 1 ]; then - sub_funchook - fi if [ $INSTALL_NETCORE = 1 ]; then sub_netcore fi @@ -927,6 +917,9 @@ sub_install(){ if [ $INSTALL_NETCORE7 = 1 ]; then sub_netcore7 fi + if [ $INSTALL_NETCORE8 = 1 ]; then + sub_netcore8 + fi if [ $INSTALL_V8 = 1 ]; then sub_v8 fi @@ -963,9 +956,6 @@ sub_install(){ if [ $INSTALL_RUST = 1 ]; then sub_rust fi - if [ $INSTALL_SWIG = 1 ]; then - sub_swig - fi if [ $INSTALL_PACK = 1 ]; then sub_pack fi @@ -1030,14 +1020,14 @@ sub_options(){ echo "netcore 7 selected" INSTALL_NETCORE7=1 fi + if [ "$option" = 'netcore8' ]; then + echo "netcore 8 selected" + INSTALL_NETCORE8=1 + fi if [ "$option" = 'rapidjson' ]; then echo "rapidjson selected" INSTALL_RAPIDJSON=1 fi - if [ "$option" = 'funchook' ]; then - echo "funchook selected" - INSTALL_FUNCHOOK=1 - fi if [ "$option" = 'v8' ] || [ "$option" = 'v8rep54' ]; then echo "v8 selected" INSTALL_V8REPO=1 @@ -1103,10 +1093,6 @@ sub_options(){ echo "rust selected" INSTALL_RUST=1 fi - if [ "$option" = 'swig' ]; then - echo "swig selected" - INSTALL_SWIG=1 - fi if [ "$option" = 'pack' ]; then echo "pack selected" INSTALL_PACK=1 @@ -1143,8 +1129,8 @@ sub_help() { echo " netcore2" echo " netcore5" echo " netcore7" + echo " netcore8" echo " rapidjson" - echo " funchook" echo " v8" echo " v8rep51" echo " v8rep54" @@ -1159,7 +1145,6 @@ sub_help() { echo " c" echo " cobol" echo " go" - echo " swig" echo " pack" echo " coverage" echo " clangformat" diff --git a/tools/metacall-license.sh b/tools/metacall-license.sh index 31c82f7b92..2be232899b 100755 --- a/tools/metacall-license.sh +++ b/tools/metacall-license.sh @@ -4,7 +4,7 @@ # MetaCall License Bash Script by Parra Studios # License bash script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -35,7 +35,7 @@ find "$EXEC_PATH" -type f \ -exec sh -c ' \ # Copyright - COPYRIGHT="Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>$" + COPYRIGHT="Copyright (C) 2016 - 2025 Vicente Eduardo Ferrer Garcia <vic798@gmail.com>$" # License LICENSE=$(cat <<-END diff --git a/tools/metacall-runtime.sh b/tools/metacall-runtime.sh index 70855f10d3..9ef4afba2d 100755 --- a/tools/metacall-runtime.sh +++ b/tools/metacall-runtime.sh @@ -4,7 +4,7 @@ # MetaCall Configuration Environment Shell Script by Parra Studios # Configure and install MetaCall environment script utility. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -170,6 +170,15 @@ sub_netcore7(){ sub_apt_install_hold dotnet-runtime-7.0=7.0.5-1 } +# NetCore 8 +sub_netcore8(){ + echo "configure netcore 8" + cd $ROOT_DIR + + # Install NET Core Runtime 8.x + wget -O - https://dot.net/v1/dotnet-install.sh | $SUDO_CMD bash -s -- --version 8.0.408 --install-dir /usr/local/bin --runtime dotnet +} + # V8 sub_v8(){ echo "configure v8" @@ -252,10 +261,10 @@ sub_java(){ # C sub_c(){ echo "configure c" + cd $ROOT_DIR + LLVM_VERSION_STRING=14 if [ "${OPERATIVE_SYSTEM}" = "Linux" ]; then - LLVM_VERSION_STRING=14 - if [ "${LINUX_DISTRO}" = "debian" ]; then UBUNTU_CODENAME="" CODENAME_FROM_ARGUMENTS="" @@ -293,9 +302,19 @@ sub_c(){ sub_apt_install_hold libffi libclang-${LLVM_VERSION_STRING} elif [ "${LINUX_DISTRO}" = "ubuntu" ]; then sub_apt_install_hold libffi libclang-${LLVM_VERSION_STRING} + elif [ "${LINUX_DISTRO}" = "alpine" ]; then + $SUDO_CMD apk add --no-cache libffi-dev + $SUDO_CMD apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/v3.16/main clang-libs=13.0.1-r1 clang-dev=13.0.1-r1 fi - - # TODO: Implement Alpine and Darwin + elif [ "${OPERATIVE_SYSTEM}" = "Darwin" ]; then + brew install libffi + brew install llvm@$LLVM_VERSION_STRING + brew link llvm@$LLVM_VERSION_STRING --force --overwrite + mkdir -p "$ROOT_DIR/build" + CMAKE_CONFIG_PATH="$ROOT_DIR/build/CMakeConfig.txt" + LIBCLANG_PREFIX=$(brew --prefix llvm@$LLVM_VERSION_STRING) + echo "-DLibClang_INCLUDE_DIR=${LIBCLANG_PREFIX}/include" >> $CMAKE_CONFIG_PATH + echo "-DLibClang_LIBRARY=${LIBCLANG_PREFIX}/lib/libclang.dylib" >> $CMAKE_CONFIG_PATH fi } diff --git a/tools/metacall-sanitizer.sh b/tools/metacall-sanitizer.sh index 81ca40a4a1..cd3f08b402 100755 --- a/tools/metacall-sanitizer.sh +++ b/tools/metacall-sanitizer.sh @@ -4,7 +4,7 @@ # MetaCall Sanitizer Bash Script by Parra Studios # Install, build and sanitizer test bash script utility for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -23,7 +23,7 @@ set -euxo pipefail BUILD_SANITIZER=${1:-address-sanitizer} BUILD_LANGUAGES=( - python ruby netcore7 nodejs typescript file rpc wasm java c cobol rust + python ruby netcore8 nodejs typescript file rpc wasm java c cobol rust ) SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) ROOT_DIR=$(dirname "$SCRIPT_DIR") @@ -35,7 +35,7 @@ if [ "${BUILD_SANITIZER}" != "address-sanitizer" ] && [ "${BUILD_SANITIZER}" != fi # Install -"${SCRIPT_DIR}/metacall-environment.sh" base ${BUILD_LANGUAGES[@]} rapidjson funchook swig pack backtrace +"${SCRIPT_DIR}/metacall-environment.sh" base ${BUILD_LANGUAGES[@]} rapidjson pack backtrace # Configure and Build export NODE_PATH="/usr/lib/node_modules" @@ -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 355e48397d..4ac47f5184 100644 --- a/tools/runtime/Dockerfile +++ b/tools/runtime/Dockerfile @@ -2,7 +2,7 @@ # MetaCall Library by Parra Studios # Docker image infrastructure for MetaCall. # -# Copyright (C) 2016 - 2024 Vicente Eduardo Ferrer Garcia <vic798@gmail.com> +# 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. @@ -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