Merge branch 'fix-cast' into master
This commit is contained in:
commit
975a36d5a5
537 changed files with 6412 additions and 29161 deletions
430
.github/workflows/ci.yml
vendored
Normal file
430
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'CHANGES*'
|
||||
- 'Doc/**'
|
||||
- 'appveyor.yml'
|
||||
pull_request:
|
||||
branches: master
|
||||
paths-ignore:
|
||||
- 'CHANGES*'
|
||||
- 'Doc/**'
|
||||
- 'appveyor.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
# When continue-on-error is true for an individual build, that build can fail (it'll show red),
|
||||
# but it won't fail the overall build
|
||||
continue-on-error: ${{ matrix.continue-on-error || false }}
|
||||
|
||||
runs-on: ${{ matrix.os || 'ubuntu-20.04' }}
|
||||
|
||||
# By default, the name of the build is the language used and SWIG options, but matrix entries
|
||||
# can define the additional "desc" field with any additional information to include in the name.
|
||||
name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY3 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- SWIGLANG: ""
|
||||
- SWIGLANG: ""
|
||||
GCC: 7
|
||||
- SWIGLANG: ""
|
||||
GCC: 8
|
||||
- SWIGLANG: ""
|
||||
GCC: 9
|
||||
- SWIGLANG: ""
|
||||
GCC: 10
|
||||
- SWIGLANG: ""
|
||||
GCC: 11
|
||||
- SWIGLANG: ""
|
||||
compiler: clang
|
||||
- SWIGLANG: csharp
|
||||
# D support can't be enabled because dmd 2.066 fails to build anything
|
||||
# under Ubuntu 18.04 due to its standard library (libphobos2.a) not
|
||||
# being compiled with -FPIC, but system gcc using -fpie by default,
|
||||
# resulting in linking errors for any output. And later versions, such
|
||||
# as 2.086.1, are not supported and result in errors in SWIG test suite.
|
||||
#
|
||||
# - SWIGLANG: d
|
||||
# VER: '2.066.0'
|
||||
# os: ubuntu-18.04 # This dlang version doesn't work under 20.04.
|
||||
- SWIGLANG: go
|
||||
VER: '1.6'
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: go
|
||||
VER: '1.8'
|
||||
- SWIGLANG: go
|
||||
VER: '1.12'
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: go
|
||||
VER: '1.17'
|
||||
- SWIGLANG: guile
|
||||
- SWIGLANG: java
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: node
|
||||
VER: '12'
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: node
|
||||
VER: '17'
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: jsc
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: v8
|
||||
os: ubuntu-18.04 # libv8-dev only actually provides v8 in 18.04.
|
||||
- SWIGLANG: lua
|
||||
- SWIGLANG: lua
|
||||
VER: '5.3'
|
||||
- SWIGLANG: octave
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: perl5
|
||||
- SWIGLANG: php
|
||||
VER: '7.4'
|
||||
- SWIGLANG: php
|
||||
- SWIGLANG: python
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.2'
|
||||
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.3'
|
||||
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.4'
|
||||
os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.5'
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.6'
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.7'
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.8'
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.9'
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
VER: '3.10'
|
||||
- SWIGLANG: python
|
||||
SWIG_FEATURES: -builtin
|
||||
- SWIGLANG: python
|
||||
SWIG_FEATURES: -builtin -O
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
SWIG_FEATURES: -builtin
|
||||
- SWIGLANG: python
|
||||
PY3: 3
|
||||
SWIG_FEATURES: -builtin -O
|
||||
- SWIGLANG: r
|
||||
- SWIGLANG: ruby
|
||||
VER: '1.9'
|
||||
os: ubuntu-18.04
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.0'
|
||||
os: ubuntu-18.04
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.1'
|
||||
os: ubuntu-18.04
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.2'
|
||||
os: ubuntu-18.04
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.3'
|
||||
os: ubuntu-18.04
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.4'
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.5'
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.6'
|
||||
- SWIGLANG: ruby
|
||||
VER: '2.7'
|
||||
- SWIGLANG: ruby
|
||||
VER: '3.0'
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: scilab
|
||||
os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
|
||||
- SWIGLANG: tcl
|
||||
# c++11 testing
|
||||
- SWIGLANG: csharp
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: go
|
||||
VER: '1.17'
|
||||
CPPSTD: c++11
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: guile
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: java
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: node
|
||||
VER: '14'
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: lua
|
||||
CPPSTD: c++11
|
||||
# - SWIGLANG: octave
|
||||
# CPPSTD: c++11
|
||||
- SWIGLANG: perl5
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: php
|
||||
CPPSTD: c++11
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: python
|
||||
CPPSTD: c++11
|
||||
PY3: 3
|
||||
- SWIGLANG: r
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: ruby
|
||||
CPPSTD: c++11
|
||||
- SWIGLANG: scilab
|
||||
CPPSTD: c++11
|
||||
os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
|
||||
- SWIGLANG: tcl
|
||||
CPPSTD: c++11
|
||||
# c++14 testing
|
||||
- SWIGLANG: csharp
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: go
|
||||
VER: '1.17'
|
||||
CPPSTD: c++14
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: guile
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: java
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: node
|
||||
VER: '16'
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: lua
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: octave
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: perl5
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: php
|
||||
CPPSTD: c++14
|
||||
CSTD: gnu11
|
||||
- SWIGLANG: python
|
||||
CPPSTD: c++14
|
||||
PY3: 3
|
||||
- SWIGLANG: r
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: ruby
|
||||
CPPSTD: c++14
|
||||
- SWIGLANG: scilab
|
||||
CPPSTD: c++14
|
||||
os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
|
||||
- SWIGLANG: tcl
|
||||
CPPSTD: c++14
|
||||
# c++17 testing (using gcc11)
|
||||
- SWIGLANG: csharp
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: go
|
||||
VER: '1.17'
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
CSTD: gnu17
|
||||
- SWIGLANG: guile
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: java
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: javascript
|
||||
ENGINE: node
|
||||
VER: '17'
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: lua
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: octave
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: perl5
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: php
|
||||
CPPSTD: c++17
|
||||
CSTD: gnu17
|
||||
GCC: 11
|
||||
- SWIGLANG: python
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
PY3: 3
|
||||
- SWIGLANG: r
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: ruby
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
- SWIGLANG: scilab
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
os: ubuntu-18.04 # scilab-6.1 in ubuntu-20.04 not yet working
|
||||
- SWIGLANG: tcl
|
||||
CPPSTD: c++17
|
||||
GCC: 11
|
||||
# Experimental languages (these are allowed to fail)
|
||||
- SWIGLANG: mzscheme
|
||||
continue-on-error: true
|
||||
- SWIGLANG: ocaml
|
||||
continue-on-error: true
|
||||
os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working
|
||||
# Run all of them, as opposed to aborting when one fails
|
||||
fail-fast: false
|
||||
|
||||
env:
|
||||
SWIGLANG: ${{ matrix.SWIGLANG }}
|
||||
PY3: ${{ matrix.PY3 }}
|
||||
VER: ${{ matrix.VER }}
|
||||
ENGINE: ${{ matrix.ENGINE }}
|
||||
SWIG_FEATURES: ${{ matrix.SWIG_FEATURES }}
|
||||
GCC: ${{ matrix.GCC }}
|
||||
CSTD: ${{ matrix.CSTD }}
|
||||
CPPSTD: ${{ matrix.CPPSTD }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install CCache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ matrix.os || 'ubuntu-20.04' }}-${{ matrix.compiler || 'gcc' }}${{ matrix.GCC }}
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
set -x
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
echo PATH="$PATH" >> $GITHUB_ENV
|
||||
|
||||
source $GITHUB_WORKSPACE/Tools/GHA-linux-install.sh
|
||||
echo WITHLANG="$WITHLANG" >> $GITHUB_ENV
|
||||
|
||||
case $(uname) in
|
||||
Linux)
|
||||
cpu_count=$(nproc)
|
||||
;;
|
||||
|
||||
Darwin)
|
||||
cpu_count=$(sysctl -n hw.ncpu)
|
||||
;;
|
||||
|
||||
*)
|
||||
cpu_count=1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ $cpu_count != 1 ]]; then
|
||||
echo SWIGJOBS=-j$cpu_count >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
if test '${{ matrix.compiler }}' = 'clang'; then
|
||||
CC="clang"
|
||||
CXX="clang++"
|
||||
|
||||
CFLAGS="$CFLAGS -fPIE"
|
||||
CXXFLAGS="$CXXFLAGS -fPIE"
|
||||
elif test -n "$GCC"; then
|
||||
CC="gcc-$GCC"
|
||||
CXX="g++-$GCC"
|
||||
else
|
||||
CC="gcc"
|
||||
CXX="g++"
|
||||
fi
|
||||
|
||||
export CC CXX
|
||||
|
||||
echo CC="$CC" >> $GITHUB_ENV
|
||||
echo CXX="$CXX" >> $GITHUB_ENV
|
||||
|
||||
ls -la $(which $CC) $(which $CXX)
|
||||
$CC --version
|
||||
$CXX --version
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
source $GITHUB_WORKSPACE/Tools/CI-linux-environment.sh
|
||||
set -x
|
||||
|
||||
if [[ -z "$CSTD" ]]; then
|
||||
case "$CPPSTD" in
|
||||
c++11) export CSTD=c11 ;;
|
||||
c++14) export CSTD=c11 ;;
|
||||
c++17) export CSTD=c17 ;;
|
||||
esac
|
||||
echo CSTD="$CSTD" >> $GITHUB_ENV
|
||||
fi
|
||||
if test -n "$CPPSTD"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
|
||||
if test -n "$CSTD"; then CONFIGOPTS+=("CFLAGS=-std=$CSTD $CFLAGS"); fi
|
||||
if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
|
||||
echo "${CONFIGOPTS[@]}"
|
||||
./autogen.sh && mkdir -p build/build && cd build/build && ../../configure "${CONFIGOPTS[@]}"
|
||||
|
||||
- name: Build
|
||||
working-directory: build/build
|
||||
run: |
|
||||
set -x
|
||||
make -s $SWIGJOBS
|
||||
./swig -version && ./swig -pcreversion
|
||||
|
||||
- name: Test
|
||||
working-directory: build/build
|
||||
run: |
|
||||
source $GITHUB_WORKSPACE/Tools/CI-linux-environment.sh
|
||||
set -x
|
||||
|
||||
if test -z "$SWIGLANG"; then
|
||||
make $SWIGJOBS check-ccache
|
||||
make $SWIGJOBS check-errors-test-suite
|
||||
else
|
||||
case "$SWIGLANG" in
|
||||
javascript)
|
||||
case "$ENGINE" in
|
||||
v8 | jsc)
|
||||
# Running tests using v8 or jsc involves creating a custom
|
||||
# interpreter in Tools/javascript, which is currently broken
|
||||
# for parallel builds (we attempt to update this interpreter
|
||||
# while running, resulting in "Text file busy" error).
|
||||
unset SWIGJOBS
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
|
||||
cflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) && echo $cflags
|
||||
cxxflags=$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) && echo $cxxflags
|
||||
make check-$SWIGLANG-version
|
||||
make check-$SWIGLANG-enabled
|
||||
make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"
|
||||
make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags"
|
||||
fi
|
||||
|
||||
- name: Install
|
||||
working-directory: build/build
|
||||
run: |
|
||||
set -x
|
||||
if test -z "$SWIGLANG"; then sudo make install && swig -version && ccache-swig -V; fi
|
||||
|
||||
- name: Clean
|
||||
working-directory: build/build
|
||||
run: |
|
||||
set -x
|
||||
make check-maintainer-clean && ../../configure
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -150,6 +150,8 @@ Examples/guile/*/my-guile
|
|||
|
||||
# Java
|
||||
Examples/test-suite/java/*/
|
||||
Examples/test-suite/java/expected.txt
|
||||
Examples/test-suite/java/got.txt
|
||||
Examples/java/*/*.java
|
||||
!Examples/java/*/runme.java
|
||||
Examples/java/doxygen/javadocs
|
||||
|
|
@ -182,11 +184,8 @@ Examples/perl5/*/*.pm
|
|||
|
||||
# PHP
|
||||
Examples/test-suite/php/php_*.h
|
||||
Examples/test-suite/php/*.php
|
||||
!Examples/test-suite/php/*runme.php
|
||||
!Examples/test-suite/php/skel.php
|
||||
Examples/php/*/php_*.h
|
||||
Examples/php/*/example.php
|
||||
Examples/php/pragmas/example.php
|
||||
|
||||
# Python
|
||||
# Based on https://github.com/github/gitignore/blob/master/Python.gitignore
|
||||
|
|
|
|||
73
.travis.yml
73
.travis.yml
|
|
@ -5,10 +5,6 @@ matrix:
|
|||
os: linux
|
||||
env: SWIGLANG=
|
||||
dist: xenial
|
||||
- compiler: clang
|
||||
os: linux
|
||||
env: SWIGLANG= BUILDSYSTEM=cmake
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=
|
||||
|
|
@ -44,6 +40,9 @@ matrix:
|
|||
- os: linux
|
||||
env: SWIGLANG= GCC=9
|
||||
dist: xenial
|
||||
- os: linux
|
||||
env: SWIGLANG= GCC=10
|
||||
dist: focal
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=csharp
|
||||
|
|
@ -66,7 +65,11 @@ matrix:
|
|||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=go VER=1.12
|
||||
env: SWIGLANG=go VER=1.12 CSTD=gnu99
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=go VER=1.16 CSTD=gnu99
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
|
|
@ -91,7 +94,14 @@ matrix:
|
|||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=12 CPP11=1
|
||||
sudo: required
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=14 CPP11=1
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=javascript ENGINE=node VER=16 CPP14=1
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
|
|
@ -131,20 +141,36 @@ matrix:
|
|||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.0
|
||||
env: SWIGLANG=php VER=7.4
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.1
|
||||
env: SWIGLANG=php VER=8.0
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.2
|
||||
dist: xenial
|
||||
env: SWIGLANG=php VER=7.0 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.3
|
||||
dist: xenial
|
||||
env: SWIGLANG=php VER=7.1 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.2 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.3 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.4 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=8.0 CONFIGOPTS=--enable-cpp11-testing CPPSTD=c++11
|
||||
dist: bionic
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=python # 2.7
|
||||
|
|
@ -271,6 +297,10 @@ matrix:
|
|||
os: linux
|
||||
env: SWIGLANG=ruby VER=2.7
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=ruby VER=3.0 CSTD=c99
|
||||
dist: xenial
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=scilab
|
||||
|
|
@ -350,11 +380,9 @@ matrix:
|
|||
os: osx
|
||||
osx_image: xcode12.2
|
||||
env: SWIGLANG=
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
env: SWIGLANG= BUILDSYSTEM=cmake
|
||||
- compiler: clang
|
||||
os: osx
|
||||
osx_image: xcode12.2
|
||||
env: SWIGLANG= BUILDSYSTEM=cmake
|
||||
- compiler: clang
|
||||
os: osx
|
||||
|
|
@ -367,7 +395,7 @@ matrix:
|
|||
- compiler: clang
|
||||
os: osx
|
||||
osx_image: xcode12.2
|
||||
env: SWIGLANG=go
|
||||
env: SWIGLANG=go CSTD=gnu99
|
||||
- compiler: clang
|
||||
os: osx
|
||||
osx_image: xcode12.2
|
||||
|
|
@ -420,11 +448,6 @@ matrix:
|
|||
os: linux
|
||||
env: SWIGLANG=d VER=2.086.1
|
||||
dist: xenial
|
||||
# seg fault in director_basic testcase
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
env: SWIGLANG=php VER=7.2
|
||||
dist: xenial
|
||||
# Experimental languages
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
|
|
@ -447,11 +470,11 @@ install:
|
|||
- if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
|
||||
- ls -la $(which $CC) $(which $CXX) && $CC --version && $CXX --version
|
||||
script:
|
||||
- if test "$BUILDSYSTEM" = "cmake"; then mkdir -p build/build && cd build/build && cmake -DCMAKE_INSTALL_PREFIX=~/.local ../.. && make install && ctest --output-on-failure -V && exit 0; fi
|
||||
- if test "$BUILDSYSTEM" = "cmake"; then cmake --version && mkdir -p build/build && cd build/build && CXXFLAGS="-Wall -Wextra -Werror" CFLAGS="-Wall -Wextra -Werror" cmake -DCMAKE_INSTALL_PREFIX=~/.local ../.. && make install && ctest --output-on-failure -V && exit 0; fi
|
||||
- echo 'Configuring...' && echo -en 'travis_fold:start:script.1\\r'
|
||||
- if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++11 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++11; fi
|
||||
- if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++14 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++14; fi
|
||||
- if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++17 -Wall -Wextra" "CFLAGS=-std=c17 -Wall -Wextra") && export CSTD=c17 && export CPPSTD=c++17; fi
|
||||
- if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++11 $CXXFLAGS" "CFLAGS=-std=c11 $CFLAGS") && export CSTD=c11 && export CPPSTD=c++11; fi
|
||||
- if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++14 $CXXFLAGS" "CFLAGS=-std=c11 $CFLAGS") && export CSTD=c11 && export CPPSTD=c++14; fi
|
||||
- if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing "CXXFLAGS=-std=c++17 $CXXFLAGS" "CFLAGS=-std=c17 $CFLAGS") && export CSTD=c17 && export CPPSTD=c++17; fi
|
||||
- if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
|
||||
- echo "${CONFIGOPTS[@]}"
|
||||
- ./autogen.sh && mkdir -p build/build && cd build/build && ../../configure "${CONFIGOPTS[@]}"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ This directory contains a version of ccache. The initial version was based on cc
|
|||
debian patches 01-02, 04-14, see the debian/patches subdirectory. The ccache-win32-2.4 modifications
|
||||
to ccache-2.4 have also been merged in.
|
||||
|
||||
Changes have been made to support cacheing the output from SWIG. The ability to cache c/c++ compiler
|
||||
Changes have been made to support caching the output from SWIG. The ability to cache c/c++ compiler
|
||||
output has been retained.
|
||||
|
||||
Additional features added are the CCACHE_VERBOSE and CCACHE_SWIG environment variables, see docs.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([ccache-swig], [0.0]) # Get version from SWIG in ccache_swig_config.h.in
|
||||
AC_PREREQ(2.52)
|
||||
AC_INIT([ccache-swig],[0.0]) # Get version from SWIG in ccache_swig_config.h.in
|
||||
AC_PREREQ([2.60])
|
||||
AC_CONFIG_SRCDIR([ccache.h])
|
||||
|
||||
AC_MSG_NOTICE([Configuring ccache])
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_FILES([config_win32.h])
|
||||
|
||||
dnl Checks for programs.
|
||||
|
|
@ -41,7 +41,7 @@ else
|
|||
fi
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
||||
AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h pwd.h sys/time.h)
|
||||
|
|
@ -51,19 +51,16 @@ AC_CHECK_FUNCS(gethostname getpwuid)
|
|||
AC_CHECK_FUNCS(utimes)
|
||||
|
||||
AC_CACHE_CHECK([for compar_fn_t in stdlib.h],ccache_cv_COMPAR_FN_T, [
|
||||
AC_TRY_COMPILE(
|
||||
[#include <stdlib.h>],
|
||||
[
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]], [[
|
||||
void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
|
||||
],
|
||||
ccache_cv_COMPAR_FN_T=yes,ccache_cv_COMPAR_FN_T=no)])
|
||||
]])],[ccache_cv_COMPAR_FN_T=yes],[ccache_cv_COMPAR_FN_T=no])])
|
||||
if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
|
||||
AC_DEFINE(HAVE_COMPAR_FN_T, 1, [ ])
|
||||
fi
|
||||
|
||||
dnl Note: This could be replaced by AC_FUNC_SNPRINTF() in the autoconf macro archive
|
||||
AC_CACHE_CHECK([for C99 vsnprintf],ccache_cv_HAVE_C99_VSNPRINTF,[
|
||||
AC_TRY_RUN([
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
void foo(const char *format, ...) {
|
||||
|
|
@ -81,8 +78,7 @@ void foo(const char *format, ...) {
|
|||
exit(0);
|
||||
}
|
||||
main() { foo("hello"); }
|
||||
],
|
||||
ccache_cv_HAVE_C99_VSNPRINTF=yes,ccache_cv_HAVE_C99_VSNPRINTF=no,ccache_cv_HAVE_C99_VSNPRINTF=cross)])
|
||||
]])],[ccache_cv_HAVE_C99_VSNPRINTF=yes],[ccache_cv_HAVE_C99_VSNPRINTF=no],[ccache_cv_HAVE_C99_VSNPRINTF=cross])])
|
||||
if test x"$ccache_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
|
||||
AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ])
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ int execute(char **argv,
|
|||
_dup2(fd, 2);
|
||||
_close(fd);
|
||||
|
||||
/* Spawn process (_exec* familly doesn't return) */
|
||||
/* Spawn process (_exec* family doesn't return) */
|
||||
status = _spawnv(_P_WAIT, argv[0], (const char **)argv);
|
||||
|
||||
/* Restore descriptors */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* for string length. This covers a nasty loophole.
|
||||
*
|
||||
* The other functions are there to prevent NULL pointers from
|
||||
* causing nast effects.
|
||||
* causing nasty effects.
|
||||
*
|
||||
* More Recently:
|
||||
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
* probably requires libm on most operating systems. Don't yet
|
||||
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
|
||||
* was pretty badly broken, it just wasn't being exercised in ways
|
||||
* which showed it, so that's been fixed. Also, formated the code
|
||||
* which showed it, so that's been fixed. Also, formatted the code
|
||||
* to mutt conventions, and removed dead code left over from the
|
||||
* original. Also, there is now a builtin-test, just compile with:
|
||||
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ on the new options.<p>
|
|||
|
||||
You can get this release from the <a href="http://ccache.samba.org/ftp/ccache/">download directory</a>
|
||||
|
||||
<p>NOTE! This release changes the hash input slighly, so you will
|
||||
<p>NOTE! This release changes the hash input slightly, so you will
|
||||
probably find that you will not get any hits against your existing
|
||||
cache when you upgrade.
|
||||
|
||||
|
|
|
|||
202
CHANGES.current
202
CHANGES.current
|
|
@ -7,6 +7,198 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.1.0 (in progress)
|
||||
===========================
|
||||
|
||||
2021-11-12: wsfulton
|
||||
[Javascript] v8 and node only. Fix mismatched new char[] and free()
|
||||
when wrapping C code char arrays. Now calloc is now used instead of
|
||||
new char[] in SWIG_AsCharPtrAndSize.
|
||||
|
||||
2021-10-03: ajrh1
|
||||
[Perl] #2074: Avoid -Wmisleading-indentation in generated code
|
||||
when using gcc11.
|
||||
|
||||
2021-10-03: jschueller
|
||||
[CMake] #2065: Add option to enable or disable PCRE support.
|
||||
|
||||
2021-09-16: ianlancetaylor
|
||||
[Go] Improved _cgo_panic implementation.
|
||||
|
||||
2021-09-16: ianlancetaylor
|
||||
[Go] Don't use crosscall2 for panicking. Instead rely on documented
|
||||
and exported interfaces.
|
||||
|
||||
2021-09-14: ianlancetaylor
|
||||
[Go] Remove -no-cgo option (long unsupported in Go)
|
||||
|
||||
2021-05-04: olly
|
||||
[PHP] #2014 Throw PHP exceptions instead of using PHP errors
|
||||
|
||||
PHP exceptions can be caught and handled if desired, but if they
|
||||
aren't caught then PHP exits in much the same way as it does for a
|
||||
PHP error.
|
||||
|
||||
In particular this means parameter type errors and some other cases
|
||||
in SWIG-generated wrappers now throw a PHP exception, which matches
|
||||
how PHP's native parameter handling deals with similar situations.
|
||||
|
||||
`SWIG_ErrorCode()`, `SWIG_ErrorMsg()`, `SWIG_FAIL()` and `goto thrown;`
|
||||
are no longer supported (these are really all internal implementation
|
||||
details and none are documented aside from brief mentions in CHANGES
|
||||
for the first three). I wasn't able to find any uses in user interface
|
||||
files at least in FOSS code via code search tools.
|
||||
|
||||
If you are using these:
|
||||
|
||||
Use `SWIG_PHP_Error(code,msg);` instead of `SWIG_ErrorCode(code);
|
||||
SWIG_ErrorMsg(msg);` (which will throw a PHP exception in SWIG >= 4.1
|
||||
and do the same as the individual calls in older SWIG).
|
||||
|
||||
`SWIG_FAIL();` and `goto thrown;` can typically be replaced with
|
||||
`SWIG_fail;`. This will probably also work with older SWIG, but
|
||||
please test with your wrappers if this is important to you.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2021-05-17: adr26
|
||||
[Python] #1985 Fix memory leaks:
|
||||
|
||||
1. Python object references were being incorrectly retained by
|
||||
SwigPyClientData, causing swig_varlink_dealloc() never to run / free
|
||||
memory. SwigPyClientData_New() / SwigPyClientData_Del() were updated
|
||||
to fix the object reference counting, causing swig_varlink_dealloc()
|
||||
to run and the memory swig_varlink owns to be freed.
|
||||
|
||||
2. SwigPyClientData itself was not freed by SwigPyClientData_Del(),
|
||||
causing another heap leak. The required free() was added to
|
||||
SwigPyClientData_Del()
|
||||
|
||||
3. Fix reference counting/leak of python cached type query
|
||||
|
||||
4. Fix reference counting/leak of SwigPyObject dict (-builtin)
|
||||
|
||||
5. Python object reference counting fixes for out-of-memory
|
||||
scenarios were added to: SWIG_Python_RaiseOrModifyTypeError(),
|
||||
SWIG_Python_AppendOutput(), SwigPyClientData_New(),
|
||||
SwigPyObject_get___dict__() and SwigPyObject_format()
|
||||
|
||||
6. Add error handling for PyModule_AddObject() to
|
||||
SWIG_Python_SetModule() (failure could be caused by OOM or a name
|
||||
clash caused by malicious code)
|
||||
|
||||
2021-05-13: olly
|
||||
[UFFI] #2009 Remove code for Common Lisp UFFI. We dropped support
|
||||
for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
|
||||
over 2 years.
|
||||
|
||||
2021-05-13: olly
|
||||
[S-EXP] #2009 Remove code for Common Lisp S-Exp. We dropped
|
||||
support for it in SWIG 4.0.0 and nobody has stepped forward to
|
||||
revive it in over 2 years.
|
||||
|
||||
2021-05-13: olly
|
||||
[Pike] #2009 Remove code for Pike. We dropped support for it in
|
||||
SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
|
||||
years.
|
||||
|
||||
2021-05-13: olly
|
||||
[Modula3] #2009 Remove code for Modula3. We dropped support for it
|
||||
in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
|
||||
years.
|
||||
|
||||
2021-05-13: olly
|
||||
[CLISP] #2009 Remove code for GNU Common Lisp. We dropped support
|
||||
for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
|
||||
over 2 years.
|
||||
|
||||
2021-05-13: olly
|
||||
[Chicken] #2009 Remove code for Chicken. We dropped support for it
|
||||
in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
|
||||
years.
|
||||
|
||||
2021-05-13: olly
|
||||
[Allegrocl] #2009 Remove code for Allegro Common Lisp. We dropped
|
||||
support for it in SWIG 4.0.0 and nobody has stepped forward to
|
||||
revive it in over 2 years.
|
||||
|
||||
2021-05-04: olly
|
||||
[PHP] #1982 #1457 https://sourceforge.net/p/swig/bugs/1339/
|
||||
SWIG now only use PHP's C API to implement its wrappers, and no
|
||||
longer generates PHP code to define classes. The wrappers should
|
||||
be almost entirely compatible with those generated before, but
|
||||
faster and without some previously hard-to-fix bugs.
|
||||
|
||||
The main notable difference is SWIG no longer generates a .php
|
||||
wrapper at all by default (only if %pragma(php) code=... or
|
||||
%pragma(php) include=... are specified in the interface file).
|
||||
This also means you need to load the module via extension=...
|
||||
in php.ini, rather than letting the dl() in the generated
|
||||
.php wrapper load it (but dl() has only worked for command-line
|
||||
PHP for some years now).
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2021-04-30: olly
|
||||
#1984 Remove support for $source and $target.
|
||||
These were officially deprecated in 2001, and attempts to use them have
|
||||
resulted in a warning (including a pointer to what to update them to)
|
||||
for most if not all of that time.
|
||||
|
||||
2021-04-27: wsfulton
|
||||
#1987 [Java] Fix %interface family of macros for returning by const
|
||||
pointer reference.
|
||||
|
||||
2021-04-19: olly
|
||||
Fix use of uninitialised variable in the generated code for an
|
||||
empty typecheck typemap, such as the dummy one we include for
|
||||
std::initializer_list.
|
||||
|
||||
2021-04-12: olly
|
||||
#1777 [Python] Specifying -py3 now generates a check for Python
|
||||
version >= 3.0.
|
||||
|
||||
2021-03-26: olly
|
||||
[PHP] Add PHP keywords 'fn' (added in 7.4) and 'match' (added in
|
||||
8.0) to the list SWIG knows to automatically rename.
|
||||
|
||||
2021-03-23: wsfulton
|
||||
#1942 [Python] Fix compilation error in wrappers when using -builtin
|
||||
and wrapping varargs in constructors.
|
||||
|
||||
2021-03-22: goto40
|
||||
#1977 Fix handling of template template parameters.
|
||||
|
||||
2021-03-21: olly
|
||||
#1929, #1978 [PHP] Add support for PHP 8.
|
||||
|
||||
2021-03-19: wsfulton
|
||||
#1610 Remove -ansi from default compilation flags.
|
||||
|
||||
2021-03-19: dot-asm
|
||||
#1934 [Java] Clean up typemaps for long long arrays.
|
||||
|
||||
2021-03-19: olly
|
||||
#1527 [PHP] Improve PHP object creation in directorin case.
|
||||
Reportedly the code we were using in this case gave segfaults in
|
||||
PHP 7.2 and later - we've been unable to reproduce these, but the
|
||||
new approach is also simpler and should be bit faster too.
|
||||
|
||||
2021-03-18: olly
|
||||
#1655 [PHP] Fix char* typecheck typemap to accept PHP Null like the
|
||||
corresponding in typemap does.
|
||||
|
||||
2021-03-18: olly
|
||||
#1900, #1905 [PHP] Fix wrapping of overloaded directed methods with
|
||||
non-void return.
|
||||
|
||||
2021-03-11: murillo128
|
||||
#1498 [Javascript] Support type conversion.
|
||||
|
||||
2021-03-06: nshmyrev
|
||||
#872 [Javascript] Various typemap issues in arrays_javascript.i fixed.
|
||||
|
||||
2021-03-03: vaughamhong
|
||||
#577 [Javascript] Implemented SetModule/GetModule for JSC to allow type sharing
|
||||
across modules.
|
||||
|
||||
2021-03-01: xantares, Oliver Buchtala, geographika
|
||||
#1040 Add support for building SWIG with CMake. See documentation in Windows.html.
|
||||
|
||||
|
|
@ -25,8 +217,14 @@ Version 4.1.0 (in progress)
|
|||
unsigned long long values.
|
||||
|
||||
2021-02-24: tomleavy, yegorich, tungntpham
|
||||
#1746 [Javascript] Add support for Node v12.
|
||||
SWIG support is now for Node v6 and later only.
|
||||
#1746 [Javascript] Add support for Node v12, v14 and v16.
|
||||
SWIG support for Node is now for v6 and later only.
|
||||
|
||||
2020-02-09: ZackerySpytz
|
||||
#1872 Fix typos in attribute2ref macros.
|
||||
|
||||
2020-10-10: wsfulton
|
||||
[Javascript] Fix so that ccomplex.i interface to file can be used.
|
||||
|
||||
2020-10-10: wsfulton
|
||||
#252 complex can now be used as a C identifier and doesn't give a syntax error.
|
||||
|
|
|
|||
|
|
@ -69,15 +69,20 @@ check_include_file_cxx ("boost/shared_ptr.hpp" HAVE_BOOST)
|
|||
check_library_exists (dl dlopen "" HAVE_LIBDL)
|
||||
check_function_exists (popen HAVE_POPEN)
|
||||
|
||||
set (PCRE_REQUIRED_ARG "REQUIRED" CACHE STRING "required arg")
|
||||
find_package (PCRE ${PCRE_REQUIRED_ARG})
|
||||
if (PCRE_FOUND)
|
||||
if (MSVC)
|
||||
set (CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}")
|
||||
endif ()
|
||||
|
||||
option (WITH_PCRE "Enable pcre" ON)
|
||||
if (WITH_PCRE)
|
||||
find_package (PCRE REQUIRED)
|
||||
set (HAVE_PCRE 1)
|
||||
include_directories (${PCRE_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
file (TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${SWIG_LIB} SWIG_LIB_WIN_UNIX)
|
||||
string (REGEX REPLACE "\\\\" "\\\\\\\\" SWIG_LIB_WIN_UNIX "${SWIG_LIB_WIN_UNIX}")
|
||||
endif ()
|
||||
configure_file (${SWIG_ROOT}/Tools/cmake/swigconfig.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,597 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG and Chicken</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
<H1><a name="Chicken">23 SWIG and Chicken</a></H1>
|
||||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#Chicken_nn2">Preliminaries</a>
|
||||
<ul>
|
||||
<li><a href="#Chicken_nn3">Running SWIG in C mode</a>
|
||||
<li><a href="#Chicken_nn4">Running SWIG in C++ mode</a>
|
||||
</ul>
|
||||
<li><a href="#Chicken_nn5">Code Generation</a>
|
||||
<ul>
|
||||
<li><a href="#Chicken_nn6">Naming Conventions</a>
|
||||
<li><a href="#Chicken_nn7">Modules</a>
|
||||
<li><a href="#Chicken_nn8">Constants and Variables</a>
|
||||
<li><a href="#Chicken_nn9">Functions</a>
|
||||
<li><a href="#Chicken_nn10">Exceptions</a>
|
||||
</ul>
|
||||
<li><a href="#Chicken_nn11">TinyCLOS</a>
|
||||
<li><a href="#Chicken_nn12">Linkage</a>
|
||||
<ul>
|
||||
<li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a>
|
||||
<li><a href="#Chicken_nn14">Building chicken extension libraries</a>
|
||||
<li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a>
|
||||
</ul>
|
||||
<li><a href="#Chicken_nn16">Typemaps</a>
|
||||
<li><a href="#Chicken_nn17">Pointers</a>
|
||||
<ul>
|
||||
<li><a href="#Chicken_collection">Garbage collection</a>
|
||||
</ul>
|
||||
<li><a href="#Chicken_nn18">Unsupported features and known problems</a>
|
||||
<ul>
|
||||
<li><a href="#Chicken_nn19">TinyCLOS problems with Chicken version <= 1.92</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
This chapter describes SWIG's support of CHICKEN. CHICKEN is a
|
||||
Scheme-to-C compiler supporting most of the language features as
|
||||
defined in the <i>Revised^5 Report on Scheme</i>. Its main
|
||||
attributes are that it
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>generates portable C code</li>
|
||||
<li>includes a customizable interpreter</li>
|
||||
<li>links to C libraries with a simple Foreign Function Interface</li>
|
||||
<li>supports full tail-recursion and first-class continuations</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
When confronted with a large C library, CHICKEN users can use
|
||||
SWIG to generate CHICKEN wrappers for the C library. However,
|
||||
the real advantages of using SWIG with CHICKEN are its
|
||||
<strong>support for C++</strong> -- object-oriented code is
|
||||
difficult to wrap by hand in CHICKEN -- and its <strong>typed
|
||||
pointer representation</strong>, essential for C and C++
|
||||
libraries involving structures or classes.
|
||||
|
||||
</p>
|
||||
|
||||
<H2><a name="Chicken_nn2">23.1 Preliminaries</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
CHICKEN support was introduced to SWIG in version 1.3.18. SWIG
|
||||
relies on some recent additions to CHICKEN, which are only
|
||||
present in releases of CHICKEN with version number
|
||||
<strong>greater than or equal to 1.89</strong>.
|
||||
To use a chicken version between 1.40 and 1.89, see the <a href="#Chicken_collection">Garbage collection</a>
|
||||
section below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You may want to look at any of the examples in Examples/chicken/
|
||||
directory for the basic steps to run SWIG CHICKEN.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn3">23.1.1 Running SWIG in C mode</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
To run SWIG CHICKEN in C mode, use
|
||||
the -chicken option.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% swig -chicken example.i</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
To allow the wrapper to take advantage of future CHICKEN code
|
||||
generation improvements, part of the wrapper is direct CHICKEN
|
||||
function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
|
||||
Scheme (<tt>example.scm</tt>). The basic Scheme code must
|
||||
be compiled to C using your system's CHICKEN compiler or
|
||||
both files can be compiled directly using the much simpler <tt>csc</tt>.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
% chicken example.scm -output-file oexample.c
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
|
||||
<tt>oexample.c</tt> are the files that must be compiled to
|
||||
object files and linked into your project.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn4">23.1.2 Running SWIG in C++ mode</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
To run SWIG CHICKEN in C++ mode, use
|
||||
the -chicken -c++ option.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% swig -chicken -c++ example.i</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This will generate <tt>example_wrap.cxx</tt> and
|
||||
<tt>example.scm</tt>. The basic Scheme code must be
|
||||
compiled to C using your system's CHICKEN compiler or
|
||||
both files can be compiled directly using the much simpler <tt>csc</tt>.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% chicken example.scm -output-file oexample.c</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
|
||||
and <tt>oexample.c</tt> are the files that must be compiled to
|
||||
object files and linked into your project.
|
||||
</p>
|
||||
|
||||
<H2><a name="Chicken_nn5">23.2 Code Generation</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Chicken_nn6">23.2.1 Naming Conventions</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Given a C variable, function or constant declaration named
|
||||
<tt>Foo_Bar</tt>, the declaration will be available
|
||||
in CHICKEN as an identifier ending with
|
||||
<tt>Foo-Bar</tt>. That is, an underscore is converted
|
||||
to a dash.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You may control what the CHICKEN identifier will be by using the
|
||||
<tt>%rename</tt> SWIG directive in the SWIG interface file.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn7">23.2.2 Modules</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The name of the module must be declared one of two ways:
|
||||
<ul>
|
||||
<li>Placing <tt>%module example</tt> in the SWIG interface
|
||||
file.</li>
|
||||
<li>Using <tt>-module example</tt> on the SWIG command
|
||||
line.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
The generated example.scm file then exports <code>(declare (unit modulename))</code>.
|
||||
If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass
|
||||
the -nounit option to SWIG.
|
||||
|
||||
<p>
|
||||
CHICKEN will be able to access the module using the <code>(declare
|
||||
(uses <i>modulename</i>))</code> CHICKEN Scheme form.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn8">23.2.3 Constants and Variables</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Constants may be created using any of the four constructs in
|
||||
the interface file:
|
||||
</p>
|
||||
<ol>
|
||||
<li><code>#define MYCONSTANT1 ...</code></li>
|
||||
<li><code>%constant int MYCONSTANT2 = ...</code></li>
|
||||
<li><code>const int MYCONSTANT3 = ...</code></li>
|
||||
<li><code>enum { MYCONSTANT4 = ... };</code></li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
In all cases, the constants may be accessed from within CHICKEN
|
||||
using the form <tt>(MYCONSTANT1)</tt>; that is, the constants
|
||||
may be accessed using the read-only parameter form.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Variables are accessed using the full parameter form.
|
||||
For example, to set the C variable "int my_variable;", use the
|
||||
Scheme form <tt>(my-variable 2345)</tt>. To get the C variable,
|
||||
use <tt>(my-variable)</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <tt>%feature("constasvar")</tt> can be applied to any constant
|
||||
or immutable variable. Instead of exporting the constant as
|
||||
a function that must be called, the constant will appear as a
|
||||
scheme variable. This causes the generated .scm file to just contain the code
|
||||
<tt>(set! MYCONSTANT1 (MYCONSTANT1))</tt>. See
|
||||
<a href="Customization.html#Customization_features">Features and the %feature directive</a>
|
||||
for info on how to apply the %feature.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn9">23.2.4 Functions</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
C functions declared in the SWIG interface file will have
|
||||
corresponding CHICKEN Scheme procedures. For example, the C
|
||||
function "int sqrt(double x);" will be available using the
|
||||
Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return
|
||||
value will give C_SCHEME_UNDEFINED as a result.
|
||||
</p>
|
||||
<p>
|
||||
A function may return more than one value by using the
|
||||
<code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i).
|
||||
They will be returned as multiple values using <code>(values)</code> if there is more than one
|
||||
result (that is, a non-void return value and at least one argout
|
||||
parameter, or a void return value and at least two argout
|
||||
parameters). The return values can then be accessed with <code>(call-with-values)</code>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn10">23.2.5 Exceptions</a></H3>
|
||||
|
||||
|
||||
<p>The SWIG chicken module has support for exceptions thrown from
|
||||
C or C++ code to be caught in scheme.
|
||||
See <a href="Customization.html#Customization_exception">Exception handling with %exception</a>
|
||||
for more information about declaring exceptions in the interface file.
|
||||
</p>
|
||||
|
||||
<p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface
|
||||
as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from
|
||||
inside the %exception blocks. <code>SWIG_exception</code> will throw a list consisting of the code
|
||||
(as an integer) and the message. Both of these will throw an exception using <code>(abort)</code>,
|
||||
which can be handled by <code>(handle-exceptions)</code>. See
|
||||
the Chicken manual on Exceptions
|
||||
and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>. Since the exception values are thrown
|
||||
directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case.
|
||||
</p>
|
||||
|
||||
<p>The following simple module</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module exception_test
|
||||
|
||||
%inline %{
|
||||
void test_throw(int i) throws (int) {
|
||||
if (i == 1) throw 15;
|
||||
}
|
||||
%}
|
||||
</pre></div>
|
||||
|
||||
<p>could be run with</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
(handle-exceptions exvar
|
||||
(if (= exvar 15)
|
||||
(print "Correct!")
|
||||
(print "Threw something else " exvar))
|
||||
(test-throw 1))
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H2><a name="Chicken_nn11">23.3 TinyCLOS</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
|
||||
"Tiny CLOS is a Scheme implementation of a 'kernelized' CLOS, with a
|
||||
metaobject protocol. The implementation is even simpler than
|
||||
the simple CLOS found in 'The Art of the Metaobject Protocol',
|
||||
weighing in at around 850 lines of code, including (some)
|
||||
comments and documentation."
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Almost all good Scheme books describe how to use metaobjects and
|
||||
generic procedures to implement an object-oriented Scheme
|
||||
system. Please consult a Scheme book if you are unfamiliar
|
||||
with the concept.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
|
||||
uses if the -proxy argument is given. If -proxy is passed, then
|
||||
the generated example.scm file will contain TinyCLOS class definitions.
|
||||
A class named Foo is declared as <Foo>, and each member variable
|
||||
is allocated a slot. Member functions are exported as generic functions.
|
||||
|
||||
<p>
|
||||
|
||||
Primitive symbols and functions (the interface that would be presented if
|
||||
-proxy was not passed) are hidden and no longer accessible. If the -unhideprimitive
|
||||
command line argument is passed to SWIG, then the primitive symbols will be
|
||||
available, but each will be prefixed by the string "primitive:"
|
||||
|
||||
<p>
|
||||
|
||||
The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments.
|
||||
If -useclassprefix is passed to SWIG, every member function will be generated with the class name
|
||||
as a prefix. If the -closprefix mymod: argument is passed to SWIG, then the exported functions will
|
||||
be prefixed by the string "mymod:". If -useclassprefix is passed, -closprefix is ignored.
|
||||
|
||||
</p>
|
||||
|
||||
<H2><a name="Chicken_nn12">23.4 Linkage</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
Please refer to <em>CHICKEN - A practical and portable Scheme
|
||||
system - User's manual</em> for detailed help on how to link
|
||||
object files to create a CHICKEN Scheme program. Briefly, to
|
||||
link object files, be sure to add <tt>`chicken-config
|
||||
-extra-libs -libs`</tt> or <tt>`chicken-config -shared
|
||||
-extra-libs -libs`</tt>to your linker options. Use the
|
||||
<tt>-shared</tt> option if you want to create a dynamically
|
||||
loadable module. You might also want to use the much simpler
|
||||
<tt>csc</tt> or <tt>csc.bat</tt>.
|
||||
</p>
|
||||
|
||||
<p>Each scheme file that is generated
|
||||
by SWIG contains <code>(declare (uses <i>modname</i>))</code>. This means that to load the
|
||||
module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Chicken_nn13">23.4.1 Static binary or shared library linked at compile time</a></H3>
|
||||
|
||||
|
||||
<p>We can easily use csc to build a static binary.</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -chicken example.i
|
||||
$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example
|
||||
$ ./example
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled
|
||||
into a shared library, and then that shared library linked when compiling the
|
||||
main application.</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -chicken example.i
|
||||
$ csc -sv example.scm example_wrap.c example_impl.c -o example.so
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The <tt>example.so</tt> file can then linked with <tt>test_script.scm</tt> when it
|
||||
is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>.
|
||||
Multiple SWIG modules could have been linked into <tt>example.so</tt> and each
|
||||
one accessed with a <code>(declare (uses ... ))</code>.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ csc -v test_script.scm -lexample
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>,
|
||||
in which case the test script does not need to be linked with example.so. The test_script.scm file can then
|
||||
be run with <tt>csi</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn14">23.4.2 Building chicken extension libraries</a></H3>
|
||||
|
||||
|
||||
<p>Building a shared library like in the above section only works if the library
|
||||
is linked at compile time with a script containing <code>(declare (uses ...))</code> or is
|
||||
loaded explicitly with <code>(load-library 'example "example.so")</code>. It is
|
||||
not the format that CHICKEN expects for extension libraries and eggs. The problem is the
|
||||
<code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file. There are
|
||||
two possible solutions to this.</p>
|
||||
|
||||
<p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code>
|
||||
is not generated. Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into
|
||||
their own shared library.</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function.
|
||||
See the
|
||||
Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.</p>
|
||||
|
||||
<p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code>
|
||||
and then compile that file into the shared library as well. For example, inside the <tt>mod_load.scm</tt> file,</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
(declare (uses mod1))
|
||||
(declare (uses mod2))
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Which would then be compiled with</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -chicken mod1.i
|
||||
$ swig -chicken mod2.i
|
||||
$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Then the extension library can be loaded with <code>(require 'mod)</code>. As we can see here,
|
||||
<tt>mod_load.scm</tt> contains the code that gets executed when the module is loaded. All this code
|
||||
does is load both mod1 and mod2. As we can see, this technique is more useful when you want to
|
||||
combine a few SWIG modules into one chicken extension library, especially if modules are related by
|
||||
<code>%import</code></p>
|
||||
|
||||
<p>In either method, the files that are compiled into the shared library could also be
|
||||
packaged into an egg. The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG
|
||||
are stand alone and do not need SWIG to be installed to be compiled. Thus the egg could be
|
||||
distributed and used by anyone, even if SWIG is not installed.</p>
|
||||
|
||||
<p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds
|
||||
two eggs, one using the first method and one using the second method.</p>
|
||||
|
||||
<H3><a name="Chicken_nn15">23.4.3 Linking multiple SWIG modules with TinyCLOS</a></H3>
|
||||
|
||||
|
||||
<p>Linking together multiple modules that share type information using the <code>%import</code>
|
||||
directive while also using <tt>-proxy</tt> is more complicated. For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the
|
||||
<tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>,
|
||||
and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported
|
||||
to the top of <tt>mod2.scm</tt>. By default, when SWIG encounters an <code>%import "modname.i"</code> directive,
|
||||
it exports <code>(declare (uses <i>modname</i>))</code> into the scm file. This works fine unless mod1 was compiled with
|
||||
the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p>
|
||||
|
||||
<p>One option is to override the automatic generation of <code>(declare (uses mod1))</code>
|
||||
by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>.
|
||||
SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive. Any scheme code inside that directive is inserted into the
|
||||
generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>.
|
||||
This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code>
|
||||
(which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p>
|
||||
|
||||
<p>The other option is to use the second idea in the above section. Compile all the modules normally, without any
|
||||
<code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>. Then the modules will import each other correctly
|
||||
with <code>(declare (uses ...))</code>.
|
||||
To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code>
|
||||
all the modules.</p>
|
||||
|
||||
<H2><a name="Chicken_nn16">23.5 Typemaps</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
The Chicken module handles all types via typemaps. This information is
|
||||
read from <code>Lib/chicken/typemaps.i</code> and
|
||||
<code>Lib/chicken/chicken.swg</code>.
|
||||
</p>
|
||||
|
||||
<H2><a name="Chicken_nn17">23.6 Pointers</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
For pointer types, SWIG uses CHICKEN tagged pointers.
|
||||
|
||||
A tagged pointer is an ordinary CHICKEN pointer with an
|
||||
extra slot for a void *. With SWIG
|
||||
CHICKEN, this void * is a pointer to a type-info
|
||||
structure. So each pointer used as input or output from
|
||||
the SWIG-generated CHICKEN wrappers will have type
|
||||
information attached to it. This will let the wrappers
|
||||
correctly determine which method should be called
|
||||
according to the object type hierarchy exposed in the SWIG
|
||||
interface files.
|
||||
</p>
|
||||
<p>
|
||||
To construct a Scheme object from a C pointer, the wrapper code
|
||||
calls the function
|
||||
<code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>,
|
||||
The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared
|
||||
<code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code>
|
||||
It is ok to call <code>SWIG_NewPointerObj</code> more than once,
|
||||
just make sure known_space has enough space for all the created pointers.
|
||||
</p>
|
||||
<p>
|
||||
To get the pointer represented by a CHICKEN tagged pointer, the
|
||||
wrapper code calls the function
|
||||
<code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>,
|
||||
passing a pointer to a struct representing the expected pointer
|
||||
type. flags is either zero or SWIG_POINTER_DISOWN (see below).
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_collection">23.6.1 Garbage collection</a></H3>
|
||||
|
||||
|
||||
<p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a
|
||||
finalizer to the type which will call the destructor or delete method of
|
||||
that type. The destructor and delete functions are no longer exported for
|
||||
use in scheme code, instead SWIG and chicken manage pointers.
|
||||
In situations where SWIG knows that a function is returning a type that should
|
||||
be garbage collected, SWIG will automatically set the owner flag to 1. For other functions,
|
||||
the <code>%newobject</code> directive must be specified for functions whose return values
|
||||
should be garbage collected. See
|
||||
<a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more information.
|
||||
</p>
|
||||
|
||||
<p>In situations where a C or C++ function will assume ownership of a pointer, and thus
|
||||
chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap.
|
||||
After applying this typemap (see the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more information on how to apply typemaps),
|
||||
any pointer that gets passed in will no longer be garbage collected.
|
||||
An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>.
|
||||
<b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might
|
||||
get deleted while the scheme code still holds a pointer to it. Further use of this pointer
|
||||
can lead to a crash.
|
||||
</p>
|
||||
|
||||
<p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection
|
||||
does not work for chicken versions below 1.89. If you would like the SWIG generated code to work with
|
||||
chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG. This will not export code
|
||||
inside the _wrap.c file to register finalizers, and will then export destructor functions which
|
||||
must be called manually.
|
||||
</p>
|
||||
|
||||
<H2><a name="Chicken_nn18">23.7 Unsupported features and known problems</a></H2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>No director support.</li>
|
||||
<li>No support for c++ standard types like std::vector.</li>
|
||||
<li>The TinyCLOS wrappers for overloaded functions will not work correctly when using
|
||||
<a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="Chicken_nn19">23.7.1 TinyCLOS problems with Chicken version <= 1.92</a></H3>
|
||||
|
||||
|
||||
<p>In Chicken versions equal to or below 1.92, TinyCLOS has a limitation such that generic methods do not properly work on methods
|
||||
with different number of specializers: TinyCLOS assumes that every method added to a generic function
|
||||
will have the same number of specializers. SWIG generates functions with different lengths of specializers
|
||||
when C/C++ functions are overloaded. For example, the code</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {};
|
||||
int foo(int a, Foo *b);
|
||||
int foo(int a);
|
||||
</pre></div>
|
||||
|
||||
<p>will produce scheme code</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
(define-method (foo (arg0 <top>) (arg1 <Foo>)) (<i>call primitive function</i>))
|
||||
(define-method (foo (arg0 <top>)) (<i>call primitive function</i>))
|
||||
</pre></div>
|
||||
|
||||
<p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one,
|
||||
so calling <code>(foo 3 f)</code> will produce an error.</p>
|
||||
|
||||
<p>There are three solutions to this. The easist is to upgrade to the latest Chicken version. Otherwise, the
|
||||
file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against
|
||||
tinyclos.scm inside the 1.92 chicken source to add support into TinyCLOS for multi-argument generics. (This patch was accepted into Chicken)
|
||||
This requires chicken to be rebuilt and custom install of chicken. An alternative is the <tt>Lib/chicken/multi-generic.scm</tt>
|
||||
file in the SWIG source. This file can be loaded after TinyCLOS is loaded, and it will override some functions
|
||||
inside TinyCLOS to correctly support multi-argument generics. Please see the comments at the top of both files for more information.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -96,6 +96,7 @@
|
|||
<li><a href="Windows.html#Windows_swig_exe">Building swig.exe on Windows</a>
|
||||
<ul>
|
||||
<li><a href="Windows.html#Windows_cmake">Building swig.exe using CMake</a>
|
||||
<li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MSYS2</a>
|
||||
<li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
|
||||
<li><a href="Windows.html#Windows_cygwin">Building swig.exe using Cygwin</a>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ Here is the list of all Doxygen tags and the description of how they are transla
|
|||
</tr>
|
||||
<tr>
|
||||
<td>\throws</td>
|
||||
<td>replaced wih ':raises:'</td>
|
||||
<td>replaced with ':raises:'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>\todo</td>
|
||||
|
|
|
|||
|
|
@ -3613,7 +3613,7 @@ A target language is given the 'Supported' status when
|
|||
Examples must be available and run successfully.
|
||||
</li>
|
||||
<li>
|
||||
The examples and test-suite must be fully functioning on the Travis Continuous Integration platform.
|
||||
The examples and test-suite must be fully functioning on the Github Actions Continuous Integration platform.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -3660,9 +3660,9 @@ Some minimum requirements and notes about languages with the 'Experimental' stat
|
|||
The number of tests in these lists should be no greater than half of the number of tests in the full test-suite.
|
||||
</li>
|
||||
<li>
|
||||
The examples and test-suite must also be fully functioning on the Travis Continuous Integration platform.
|
||||
However, experimental languages will be set as 'allow_failures'.
|
||||
This means that pull requests and normal development commits will not break the entire Travis build should an experimental language fail.
|
||||
The examples and test-suite must also be fully functioning on the Github Actions Continuous Integration platform.
|
||||
However, experimental languages will be flagged as 'continue-on-error'.
|
||||
This means that pull requests and normal development commits will not break the entire Github Actions build should an experimental language fail.
|
||||
</li>
|
||||
<li>
|
||||
Any new failed tests will be fixed on a 'best effort' basis by core developers with no promises made.
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ code. SWIG fills this gap.
|
|||
There are (at least) two different Go compilers. The first is the gc compiler
|
||||
of the <a href="https://golang.org/doc/install">Go distribution</a>, normally
|
||||
invoked via the <a href="https://golang.org/cmd/go/">go tool</a>.
|
||||
SWIG supports the gc compiler version 1.2 or later.
|
||||
The second Go compiler is the <a href="https://golang.org/doc/install/gccgo">
|
||||
gccgo compiler</a>, which is a frontend to the GCC compiler suite.
|
||||
The interface to C/C++ code is completely different for the two Go compilers.
|
||||
|
|
@ -142,44 +143,6 @@ You will now have a Go package that you can import from other Go packages as
|
|||
usual.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG can be used without cgo, via the <tt>-no-cgo</tt> option, but
|
||||
more steps are required. This only works with Go versions before 1.5.
|
||||
When using Go version 1.2 or later, or when using gccgo, the code
|
||||
generated by SWIG can be linked directly into the Go program. A
|
||||
typical command sequence when using the Go compiler of the Go
|
||||
distribution would look like this:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
% swig -go -no-cgo example.i
|
||||
% gcc -c code.c # The C library being wrapped.
|
||||
% gcc -c example_wrap.c
|
||||
% go tool 6g example.go
|
||||
% go tool 6c example_gc.c
|
||||
% go tool pack grc example.a example.6 example_gc.6 code.o example_wrap.o
|
||||
% go tool 6g main.go
|
||||
% go tool 6l main.6
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
You can also put the wrapped code into a shared library, and when using the Go
|
||||
versions before 1.2 this is the only supported option. A typical command
|
||||
sequence for this approach would look like this:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
% swig -go -no-cgo -use-shlib example.i
|
||||
% gcc -c -fpic example.c
|
||||
% gcc -c -fpic example_wrap.c
|
||||
% gcc -shared example.o example_wrap.o -o example.so
|
||||
% go tool 6g example.go
|
||||
% go tool 6c example_gc.c
|
||||
% go tool pack grc example.a example.6 example_gc.6
|
||||
% go tool 6g main.go # your code, not generated by SWIG
|
||||
% go tool 6l main.6
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Go_commandline">25.3.1 Go-specific Commandline Options</a></H3>
|
||||
|
||||
|
|
@ -206,9 +169,7 @@ swig -go -help
|
|||
|
||||
<tr>
|
||||
<td>-no-cgo</td>
|
||||
<td>Generate files that can be used directly, rather than via the Go
|
||||
cgo tool. This option does not work with Go 1.5 or later. It is
|
||||
required for versions of Go before 1.2.</td>
|
||||
<td>This option is no longer supported.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
|
@ -279,13 +240,10 @@ swig -go -help
|
|||
<H3><a name="Go_outputs">25.3.2 Generated Wrapper Files</a></H3>
|
||||
|
||||
|
||||
<p>There are two different approaches to generating wrapper files,
|
||||
controlled by SWIG's <tt>-no-cgo</tt> option. The <tt>-no-cgo</tt>
|
||||
option only works with version of Go before 1.5. It is required
|
||||
when using versions of Go before 1.2.</p>
|
||||
|
||||
<p>With or without the <tt>-no-cgo</tt> option, SWIG will generate the
|
||||
following files when generating wrapper code:</p>
|
||||
<p>
|
||||
SWIG will generate the following files when generating wrapper
|
||||
code:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
|
|
@ -308,17 +266,6 @@ or C++ compiler.
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
<p>When the <tt>-no-cgo</tt> option is used, and the <tt>-gccgo</tt>
|
||||
option is not used, SWIG will also generate an additional file:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
MODULE_gc.c will contain C code which should be compiled with the C
|
||||
compiler distributed as part of the gc compiler. It should then be
|
||||
combined with the compiled MODULE.go using go tool pack.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<H2><a name="Go_basic_tour">25.4 A tour of basic C/C++ wrapping</a></H2>
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ information by including a directive like this in the interface file:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
(The <code>%scheme</code> directive allows to insert arbitrary Scheme
|
||||
(The <code>%scheme</code> directive allows inserting arbitrary Scheme
|
||||
code into the generated file <code><var>module.scm</var></code>; it is
|
||||
placed between the <code>define-module</code> form and the
|
||||
<code>export</code> form.)
|
||||
|
|
|
|||
|
|
@ -9095,7 +9095,7 @@ This method normally calls the C++ destructor or <tt>free()</tt> for C code.
|
|||
<p>
|
||||
The generated code can be debugged using both a Java debugger and a C++ debugger using the usual debugging techniques.
|
||||
Breakpoints can be set in either Java or C++ code and so both can be debugged simultaneously.
|
||||
Most debuggers do not understand both Java and C++, with one noteable exception of Sun Studio,
|
||||
Most debuggers do not understand both Java and C++, with one notable exception of Sun Studio,
|
||||
where it is possible to step from Java code into a JNI method within one environment.
|
||||
</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -89,19 +89,24 @@ $ swig -javascript -jsc example.i</pre>
|
|||
<pre>
|
||||
$ swig -c++ -javascript -jsc example.i</pre>
|
||||
</div>
|
||||
<p>The V8 code that SWIG generates should work with most versions from 3.11.10 up to 3.29.14 and later.</p>
|
||||
<p>The API headers for V8 >= 4.3.0 define constants which SWIG can use to
|
||||
determine the V8 version it is compiling for. For versions < 4.3.0, you
|
||||
<p>The V8 code that SWIG generates should work with most versions from 3.11.10.
|
||||
However, the only early version that receives some testing is 3.14.5, which is
|
||||
still shipped with Ubuntu for some reason. Other than that it's probably safer
|
||||
to assume that versions earlier than 5.0 are no longer supported. Keep in mind
|
||||
that these are V8 versions, not Node.js. To give some perspective, Node.js v6.0
|
||||
uses V8 5.0, v12.0 - 7.4, v14.0 - 8.1...</p>
|
||||
<p>The API headers for V8 >= 4.3.10 define constants which SWIG can use to
|
||||
determine the V8 version it is compiling for. For versions < 4.3.10, you
|
||||
need to specify the V8 version when running SWIG. This is specified as a hex
|
||||
constant, but the constant is read as pairs of decimal digits, so for V8
|
||||
3.25.30 use constant 0x032530. This scheme can't represent components > 99,
|
||||
but this constant is only useful for V8 < 4.3.0, and no V8 versions from
|
||||
but this constant is only useful for V8 < 4.3.10, and no V8 versions from
|
||||
that era had a component > 99. For example:</p>
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i</pre>
|
||||
</div>
|
||||
<p>If you're targeting V8 >= 4.3.0, you would just run swig like so:</p>
|
||||
<p>If you're targeting V8 >= 4.3.10, you would just run swig like so:</p>
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -c++ -javascript -v8 example.i</pre>
|
||||
|
|
@ -401,7 +406,7 @@ the main window.</p>
|
|||
|
||||
<p>
|
||||
As known from <code>node.js</code> one can use <code>require</code> to load javascript modules.
|
||||
Additionally, <code>node-webkit</code> provides an API that allows to manipulate the window's menu,
|
||||
Additionally, <code>node-webkit</code> provides an API that allows manipulating the window's menu,
|
||||
open new windows, and many more things.
|
||||
</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,942 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG and Modula-3</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<H1><a name="Modula3">31 SWIG and Modula-3</a></H1>
|
||||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#Modula3_modula3_overview">Overview</a>
|
||||
<ul>
|
||||
<li><a href="#Modula3_motivation">Motivation</a>
|
||||
</ul>
|
||||
<li><a href="#Modula3_conception">Conception</a>
|
||||
<ul>
|
||||
<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
|
||||
<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
|
||||
</ul>
|
||||
<li><a href="#Modula3_preliminaries">Preliminaries</a>
|
||||
<ul>
|
||||
<li><a href="#Modula3_compilers">Compilers</a>
|
||||
<li><a href="#Modula3_commandline">Additional Commandline Options</a>
|
||||
</ul>
|
||||
<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#Modula3_inoutparam">Inputs and outputs</a>
|
||||
<li><a href="#Modula3_ordinals">Subranges, Enumerations, Sets</a>
|
||||
<li><a href="#Modula3_class">Objects</a>
|
||||
<li><a href="#Modula3_imports">Imports</a>
|
||||
<li><a href="#Modula3_exceptions">Exceptions</a>
|
||||
<li><a href="#Modula3_typemap_example">Example</a>
|
||||
</ul>
|
||||
<li><a href="#Modula3_hints">More hints to the generator</a>
|
||||
<ul>
|
||||
<li><a href="#Modula3_features">Features</a>
|
||||
<li><a href="#Modula3_pragmas">Pragmas</a>
|
||||
</ul>
|
||||
<li><a href="#Modula3_remarks">Remarks</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
This chapter describes SWIG's support for
|
||||
<a href="http://modula3.org/">Modula-3</a>.
|
||||
You should be familiar with the
|
||||
<a href="SWIG.html#SWIG">basics</a>
|
||||
of SWIG,
|
||||
especially
|
||||
<a href="Typemaps.html#Typemaps">typemaps</a>.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modula3_modula3_overview">31.1 Overview</a></H2>
|
||||
|
||||
|
||||
<p>
|
||||
Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2,
|
||||
which is in turn a successor to Pascal.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG's Modula-3 support is currently very basic and highly experimental!
|
||||
Many features are still not designed satisfyingly
|
||||
and I need more discussion about the odds and ends.
|
||||
Don't rely on any feature, incompatible changes are likely in the future!
|
||||
However, the Modula-3 generator was already useful for interfacing
|
||||
to the libraries:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
|
||||
PLPlot
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
|
||||
FFTW
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<H3><a name="Modula3_motivation">31.1.1 Motivation</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Although it is possible to write Modula-3 code that performs as well as C/C++
|
||||
most existing libraries are not written in Modula-3 but in C or C++, and
|
||||
even libraries in other languages may provide C header files.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Fortunately Modula-3 can call C functions, but you have to write Modula-3
|
||||
interfaces to them, and to make things comfortable you will also need
|
||||
wrappers that convert between high-level features of Modula-3 (garbage
|
||||
collecting, exceptions) and the explicit tracking of allocated memory and
|
||||
exception codes used by C APIs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG converts C headers to Modula-3 interfaces for you, and using typemaps
|
||||
you can pass <tt>TEXT</tt>s or open arrays, and convert error return codes
|
||||
into exceptions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the library API is ill designed
|
||||
writing appropriate typemaps can still be time-consuming.
|
||||
E.g. C programmers are very creative to work-around
|
||||
missing data types like (real) enumerations and sets.
|
||||
You should turn such work-arounds back to the Modula-3 way
|
||||
otherwise you lose static safety and consistency.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Without SWIG you would probably never consider trying to call C++ libraries
|
||||
from Modula-3, but with SWIG this is becomes feasible.
|
||||
SWIG can generate C wrappers to C++ functions and object methods
|
||||
that may throw exceptions, and then wrap these C wrappers for Modula-3.
|
||||
To make it complete you can then hide the C interface with Modula-3 classes and
|
||||
exceptions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG allows you to call C and C++ libraries from Modula-3 (even with call back
|
||||
functions), but it doesn't allow you to easily integrate a Modula-3 module into
|
||||
a C/C++ project.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modula3_conception">31.2 Conception</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Modula3_cinterface">31.2.1 Interfaces to C libraries</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Modula-3 has integrated support for calling C functions.
|
||||
This is also extensively used by the standard Modula-3 libraries
|
||||
to call OS functions.
|
||||
The Modula-3 part of SWIG and the corresponding SWIG library
|
||||
modula3.swg
|
||||
contain code that uses these features.
|
||||
Because of the built-in support there is no need
|
||||
for calling the SWIG kernel to generate wrappers written in C.
|
||||
All conversion and argument checking can be done in Modula-3
|
||||
and the interfacing is quite efficient.
|
||||
All you have to do is to write pieces of Modula-3 code
|
||||
that SWIG puts together.
|
||||
</p>
|
||||
|
||||
<table border summary="Modula-3 C library support">
|
||||
<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
|
||||
<tr>
|
||||
<td>Pragma <tt><* EXTERNAL *></tt></td>
|
||||
<td>Precedes a declaration of a PROCEDURE that is implemented
|
||||
in an external library instead of a Modula-3 module.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pragma <tt><* CALLBACK *></tt></td>
|
||||
<td>Precedes a declaration of a PROCEDURE that should be called
|
||||
by external library code.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module <tt>Ctypes</tt></td>
|
||||
<td>Contains Modula-3 types that match some basic C types.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module <tt>M3toC</tt></td>
|
||||
<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
|
||||
and C's <tt>char *</tt> type.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
In each run of SWIG the Modula-3 part
|
||||
generates several files:
|
||||
</p>
|
||||
<table border summary="Modula-3 generated files">
|
||||
<tr>
|
||||
<th>Module name scheme</th>
|
||||
<th>Identifier for <tt>%insert</tt></th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module<tt>Raw.i3</tt></td>
|
||||
<td><tt>m3rawintf</tt></td>
|
||||
<td>Declaration of types that are equivalent to those of the C library,
|
||||
<tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module<tt>Raw.m3</tt></td>
|
||||
<td><tt>m3rawimpl</tt></td>
|
||||
<td>Almost empty.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module<tt>.i3</tt></td>
|
||||
<td><tt>m3wrapintf</tt></td>
|
||||
<td>Declaration of comfortable wrappers to the C library functions.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module<tt>.m3</tt></td>
|
||||
<td><tt>m3wrapimpl</tt></td>
|
||||
<td>Implementation of the wrappers that
|
||||
convert between Modula-3 and C types,
|
||||
check for validity of values,
|
||||
hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
|
||||
and raises exceptions.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>m3makefile</tt></td>
|
||||
<td><tt>m3makefile</tt></td>
|
||||
<td>Add the modules above to the Modula-3 project and
|
||||
specify the name of the Modula-3 wrapper library
|
||||
to be generated.
|
||||
|
||||
Today I'm not sure if it is a good idea
|
||||
to create a <tt>m3makefile</tt> in each run,
|
||||
because SWIG must be started for each Modula-3 module it creates.
|
||||
Thus the m3makefile is overwritten each time. :-(
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Here's a scheme of how the function calls to Modula-3 wrappers
|
||||
are redirected to C library functions:
|
||||
</p>
|
||||
|
||||
<table summary="Modula-3 C library">
|
||||
<tr>
|
||||
<td align=center>
|
||||
Modula-3 wrapper<br>
|
||||
Module<tt>.i3</tt><br>
|
||||
generated by Modula-3 part of SWIG
|
||||
</td>
|
||||
<td></td>
|
||||
<td align=center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center>
|
||||
<!-- pre tag overrides centering -->
|
||||
|<br>
|
||||
v
|
||||
</td>
|
||||
<td></td>
|
||||
<td align=center></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center>
|
||||
Modula-3 interface to C<br>
|
||||
Module<tt>Raw.i3</tt><br>
|
||||
generated by Modula-3 part of SWIG
|
||||
</td>
|
||||
<td>--></td>
|
||||
<td align=center>
|
||||
C library
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<p>
|
||||
I have still no good conception how one can split C library interfaces
|
||||
into type oriented interfaces.
|
||||
A Module in Modula-3 represents an Abstract DataType
|
||||
(or call it a static classes, i.e. a class without virtual methods).
|
||||
E.g. if you have a principal type, say <tt>Database</tt>,
|
||||
it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
|
||||
where the database type is declared with the name <tt>T</tt>
|
||||
and where all functions are declared that operates on it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The normal operation of SWIG is to generate a fixed set of files per call.
|
||||
To generate multiple modules one has to write one SWIG interface
|
||||
(different SWIG interfaces can share common data) per module.
|
||||
Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
|
||||
and the principal type must be renamed (<tt>%typemap</tt>).
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Modula3_cppinterface">31.2.2 Interfaces to C++ libraries</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Interfaces to C++ files are much more complicated and
|
||||
there are some more design decisions that are not made, yet.
|
||||
Modula-3 has no support for C++ functions
|
||||
but C++ compilers should support generating C++ functions
|
||||
with a C interface.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here's a scheme of how the function calls to Modula-3 wrappers
|
||||
are redirected to C library functions:
|
||||
</p>
|
||||
|
||||
<table summary="Modula-3 C++ library">
|
||||
<tr>
|
||||
<td align=center>
|
||||
Modula-3 wrapper<br>
|
||||
Module<tt>.i3</tt><br>
|
||||
generated by Modula-3 part of SWIG
|
||||
</td>
|
||||
<td></td>
|
||||
<td align=center>C++ library</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center>
|
||||
<!-- pre tag overrides centering -->
|
||||
|<br>
|
||||
v
|
||||
</td>
|
||||
<td></td>
|
||||
<td align=center>
|
||||
^<br>
|
||||
|
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center>
|
||||
Modula-3 interface to C<br>
|
||||
Module<tt>Raw.i3</tt><br>
|
||||
generated by Modula-3 part of SWIG
|
||||
</td>
|
||||
<td>--></td>
|
||||
<td align=center>
|
||||
C interface to C++<br>
|
||||
module<tt>_wrap.cxx</tt><br>
|
||||
generated by the SWIG core
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Wrapping C++ libraries arises additional problems:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Is it sensible to wrap C++ classes with Modula-3 classes?
|
||||
</li>
|
||||
<li>
|
||||
How to find the wrapping Modula-3 class
|
||||
for a class pointer that is returned by a C++ routine?
|
||||
</li>
|
||||
<li>
|
||||
How to deal with multiple inheritance
|
||||
which was neglected for Modula-3 for good reasons?
|
||||
</li>
|
||||
<li>
|
||||
Is it possible to sub-class C++ classes with Modula-3 code?
|
||||
This issue is addressed by directors,
|
||||
a feature that was experimentally added to some Language modules
|
||||
like
|
||||
<a href="Java.html#Java_directors">Java</a> and
|
||||
<a href="Python.html#Python_directors">Python</a>.
|
||||
</li>
|
||||
<li>
|
||||
How to manage storage with the garbage collector of Modula-3?
|
||||
Support for
|
||||
<a href="Customization.html#Customization_ownership">
|
||||
<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
|
||||
isn't implemented, yet.
|
||||
What's about resources that are managed by the garbage collector
|
||||
but shall be passed back to the storage management of the C++ library?
|
||||
This is a general issue which is not solved in a satisfying fashion
|
||||
as far as I know.
|
||||
</li>
|
||||
<li>
|
||||
How to turn C++ exceptions into Modula-3 exceptions?
|
||||
There's also no support for
|
||||
<a href="Customization.html#Customization_exception">
|
||||
<tt>%exception</tt></a>, yet.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Be warned:
|
||||
There is no C++ library I wrote a SWIG interface for,
|
||||
so I'm not sure if this is possible or sensible, yet.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modula3_preliminaries">31.3 Preliminaries</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Modula3_compilers">31.3.1 Compilers</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
There are different Modula-3 compilers around:
|
||||
cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3.
|
||||
SWIG itself does not contain compiler specific code
|
||||
but the modula3.swg library file
|
||||
may do so.
|
||||
For testing examples I use Critical Mass cm3.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Modula3_commandline">31.3.2 Additional Commandline Options</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
There are some experimental command line options
|
||||
that prevent SWIG from generating interface files.
|
||||
Instead files are emitted that may assist you
|
||||
when writing SWIG interface files.
|
||||
</p>
|
||||
|
||||
<table border summary="Modula-3 specific options">
|
||||
<tr>
|
||||
<th>Modula-3 specific options</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top>-generateconst <file></td>
|
||||
<td>
|
||||
Disable generation of interfaces and wrappers.
|
||||
Instead write code for computing numeric values of constants
|
||||
to the specified file.
|
||||
<br>
|
||||
C code may contain several constant definitions
|
||||
written as preprocessor macros.
|
||||
Other language modules of SWIG use
|
||||
compute-once-use-readonly variables or
|
||||
functions to wrap such definitions.
|
||||
All of them can invoke C code dynamically
|
||||
for computing the macro values.
|
||||
But if one wants to turn them into Modula-3
|
||||
integer constants, enumerations or set types,
|
||||
the values of these expressions has to be known statically.
|
||||
Although definitions like <tt>(1 << FLAG_MAXIMIZEWINDOW)</tt>
|
||||
must be considered as good C style
|
||||
they are hard to convert to Modula-3
|
||||
since the value computation can use every feature of C.
|
||||
<br>
|
||||
Thus I implemented these switch
|
||||
to extract all constant definitions
|
||||
and write a C program that output the values of them.
|
||||
It works for numeric constants only
|
||||
and treats all of them as <tt>double</tt>.
|
||||
Future versions may generate a C++ program
|
||||
that can detect the type of the macros
|
||||
by overloaded output functions.
|
||||
Then strings can also be processed.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top>-generaterename <file></td>
|
||||
<td>
|
||||
Disable generation of interfaces and wrappers.
|
||||
Instead generate suggestions for <tt>%rename</tt>.
|
||||
<br>
|
||||
C libraries use a naming style
|
||||
that is neither homogeneous nor similar to that of Modula-3.
|
||||
C function names often contain a prefix denoting the library
|
||||
and some name components separated by underscores
|
||||
or capitalization changes.
|
||||
To get library interfaces that are really Modula-3 like
|
||||
you should rename the function names with the <tt>%rename</tt> directive.
|
||||
This switch outputs a list of such directives
|
||||
with a name suggestion generated by a simple heuristic.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top>-generatetypemap <file></td>
|
||||
<td>
|
||||
Disable generation of interfaces and wrappers.
|
||||
Instead generate templates for some basic typemaps.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<H2><a name="Modula3_typemaps">31.4 Modula-3 typemaps</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Modula3_inoutparam">31.4.1 Inputs and outputs</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Each C procedure has a bunch of inputs and outputs.
|
||||
Inputs are passed as function arguments,
|
||||
outputs are updated referential arguments and
|
||||
the function value.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each C type can have several typemaps
|
||||
that apply only in case if a type is used
|
||||
for an input argument, for an output argument,
|
||||
or for a return value.
|
||||
A further typemap may specify
|
||||
the direction that is used for certain parameters.
|
||||
I have chosen this separation
|
||||
in order to be able to write general typemaps for the modula3.swg typemap library.
|
||||
In the library code the final usage of the type is not known.
|
||||
Using separate typemaps for each possible use
|
||||
allows appropriate definitions for each case.
|
||||
If these pre-definitions are fine
|
||||
then the direction of the function parameter
|
||||
is the only hint the user must give.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The typemaps specific to Modula-3 have a common name scheme:
|
||||
A typemap name starts with "m3",
|
||||
followed by "raw" or "wrap"
|
||||
depending on whether it controls the generation
|
||||
of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
|
||||
It follows an "in" for typemaps applied to input argument,
|
||||
"out" for output arguments, "arg" for all kind of arguments,
|
||||
"ret" for returned values.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The main task of SWIG is to build wrapper function,
|
||||
i.e. functions that convert values between C and Modula-3
|
||||
and call the corresponding C function.
|
||||
Modula-3 wrapper functions generated by SWIG
|
||||
consist of the following parts:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Generate <tt>PROCEDURE</tt> signature.</li>
|
||||
<li>Declare local variables.</li>
|
||||
<li>Convert input values from Modula-3 to C.</li>
|
||||
<li>Check for input value integrity.</li>
|
||||
<li>Call the C function.</li>
|
||||
<li>Check returned values, e.g. error codes.</li>
|
||||
<li>Convert and write back values into Modula-3 records.</li>
|
||||
<li>Free temporary storage.</li>
|
||||
<li>Return values.</li>
|
||||
</ul>
|
||||
|
||||
<table border summary="Modula-3 typemaps">
|
||||
<tr>
|
||||
<th>Typemap</th>
|
||||
<th>Example</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapargvar</td>
|
||||
<td><tt>$1: INTEGER := $1_name;</tt></td>
|
||||
<td>
|
||||
Declaration of some variables needed for temporary results.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapargconst</td>
|
||||
<td><tt>$1 = "$1_name";</tt></td>
|
||||
<td>
|
||||
Declaration of some constant, maybe for debug purposes.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapargraw</td>
|
||||
<td><tt>ORD($1_name)</tt></td>
|
||||
<td>
|
||||
The expression that should be passed as argument to the raw Modula-3 interface function.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapargdir</td>
|
||||
<td><tt>out</tt></td>
|
||||
<td>
|
||||
Referential arguments can be used for input, output, update.
|
||||
???
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapinmode</td>
|
||||
<td><tt>READONLY</tt></td>
|
||||
<td>
|
||||
One of Modula-3 parameter modes
|
||||
<tt>VALUE</tt> (or empty),
|
||||
<tt>VAR</tt>,
|
||||
<tt>READONLY</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapinname</td>
|
||||
<td></td>
|
||||
<td>
|
||||
New name of the input argument.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapintype</td>
|
||||
<td></td>
|
||||
<td>
|
||||
Modula-3 type of the input argument.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapindefault</td>
|
||||
<td></td>
|
||||
<td>
|
||||
Default value of the input argument
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapinconv</td>
|
||||
<td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
|
||||
<td>
|
||||
Statement for converting the Modula-3 input value to C compliant value.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapincheck</td>
|
||||
<td><tt>IF Text.Length($1_name) > 10 THEN RAISE E("str too long"); END;</tt></td>
|
||||
<td>
|
||||
Check the integrity of the input value.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapoutname</td>
|
||||
<td></td>
|
||||
<td>
|
||||
Name of the <tt>RECORD</tt> field to be used for returning multiple values.
|
||||
This applies to referential output arguments that shall be turned
|
||||
into return values.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapouttype</td>
|
||||
<td></td>
|
||||
<td>
|
||||
Type of the value that is returned instead of a referential output argument.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapoutconv</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapoutcheck</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapretraw</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapretname</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wraprettype</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapretvar</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapretconv</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapretcheck</td>
|
||||
<td></td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>m3wrapfreearg</td>
|
||||
<td><tt>M3toC.FreeSharedS(str, arg1);</tt></td>
|
||||
<td>
|
||||
Free resources that were temporarily used in the wrapper.
|
||||
Since this step should never be skipped,
|
||||
SWIG will put it in the <tt>FINALLY</tt> branch
|
||||
of a <tt>TRY .. FINALLY</tt> structure.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<H3><a name="Modula3_ordinals">31.4.2 Subranges, Enumerations, Sets</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Subranges, enumerations, and sets are machine oriented types
|
||||
that make Modula very strong and expressive compared
|
||||
with the type systems of many other languages.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Subranges are used for statically restricted choices of integers.
|
||||
</li>
|
||||
<li>
|
||||
Enumerations are used for named choices.
|
||||
</li>
|
||||
<li>
|
||||
Sets are commonly used for flag (option) sets.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Using them extensively makes Modula code very safe and readable.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
C supports enumerations, too, but they are not as safe as the ones of Modula.
|
||||
Thus they are abused for many things:
|
||||
For named choices, for integer constant definitions, for sets.
|
||||
To make it complete every way of defining a value in C
|
||||
(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
|
||||
is somewhere used for defining something
|
||||
that must be handled completely different in Modula-3
|
||||
(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
|
||||
that split the task up into converting
|
||||
the C bit patterns (integer or bit set)
|
||||
into Modula-3 bit patterns (integer or bit set)
|
||||
and change the type as requested.
|
||||
See the corresponding example in the
|
||||
Examples/modula3/enum/example.i file.
|
||||
This is quite messy and not satisfying.
|
||||
So the best what you can currently do is
|
||||
to rewrite constant definitions manually.
|
||||
Though this is a tedious work
|
||||
that I'd like to automate.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Modula3_class">31.4.3 Objects</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
|
||||
while it is tried to retain the access hierarchy
|
||||
"public - protected - private" using partial revelation.
|
||||
Though the example in
|
||||
Examples/modula3/class/example.i
|
||||
is not really useful, yet.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Modula3_imports">31.4.4 Imports</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Pieces of Modula-3 code provided by typemaps
|
||||
may contain identifiers from foreign modules.
|
||||
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
|
||||
contains code using the function <tt>M3toC.SharedTtoS</tt>
|
||||
you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
|
||||
Then the module <tt>M3toC</tt> is imported
|
||||
if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
|
||||
is used at least once.
|
||||
Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
|
||||
if you need module renaming.
|
||||
Unqualified import is not supported.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is cumbersome to add this typemap to each piece of Modula-3 code.
|
||||
It is especially useful when writing general typemaps
|
||||
for the modula3.swg typemap library.
|
||||
For a monolithic module you might be better off
|
||||
if you add the imports directly:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%insert(m3rawintf) %{
|
||||
IMPORT M3toC;
|
||||
%}
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Modula3_exceptions">31.4.5 Exceptions</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Modula-3 provides another possibility
|
||||
of an output of a function: exceptions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Any piece of Modula-3 code that SWIG inserts
|
||||
due to a typemap can raise an exception.
|
||||
This way you can also convert an error code
|
||||
from a C function into a Modula-3 exception.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <tt>RAISES</tt> clause is controlled
|
||||
by typemaps with the <tt>throws</tt> extension.
|
||||
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
|
||||
contains code that may raise the exceptions <tt>OSError.E</tt>
|
||||
you should declare
|
||||
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Modula3_typemap_example">31.4.6 Example</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The generation of wrappers in Modula-3 needs very fine control
|
||||
to take advantage of the language features.
|
||||
Here is an example of a generated wrapper
|
||||
where almost everything is generated by a typemap:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I>
|
||||
PROCEDURE Name (READONLY str : TEXT := "" )
|
||||
<I> (* m3wrapoutcheck:throws *)</I>
|
||||
: NameResult RAISES {E} =
|
||||
CONST
|
||||
arg1name = "str"; <I>(* m3wrapargconst *)</I>
|
||||
VAR
|
||||
arg0 : C.char_star; <I>(* m3wrapretvar *)</I>
|
||||
arg1 : C.char_star; <I>(* m3wrapargvar *)</I>
|
||||
arg2 : C.int;
|
||||
result : RECORD
|
||||
<I> (*m3wrapretname m3wraprettype*)</I>
|
||||
unixPath : TEXT;
|
||||
<I> (*m3wrapoutname m3wrapouttype*)</I>
|
||||
checksum : CARDINAL;
|
||||
END;
|
||||
BEGIN
|
||||
TRY
|
||||
arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
|
||||
IF Text.Length(arg1) > 10 THEN <I>(* m3wrapincheck *)</I>
|
||||
RAISE E("str too long");
|
||||
END;
|
||||
<I> (* m3wrapretraw m3wrapargraw *)</I>
|
||||
arg0 := MessyToUnix (arg1, arg2);
|
||||
result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I>
|
||||
result.checksum := arg2; <I>(* m3wrapoutconv *)</I>
|
||||
IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I>
|
||||
RAISE E("invalid checksum");
|
||||
END;
|
||||
FINALLY
|
||||
M3toC.FreeSharedS(str, arg1); <I>(* m3wrapfreearg *)</I>
|
||||
END;
|
||||
END Name;
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H2><a name="Modula3_hints">31.5 More hints to the generator</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Modula3_features">31.5.1 Features</a></H3>
|
||||
|
||||
|
||||
<table border summary="Modula-3 features">
|
||||
<tr>
|
||||
<th>Feature</th>
|
||||
<th>Example</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>multiretval</td>
|
||||
<td><tt>%m3multiretval get_box;</tt> or
|
||||
<tt>%feature("modula3:multiretval") get_box;</tt></td>
|
||||
<td>Let the denoted function return a <tt>RECORD</tt>
|
||||
rather than a plain value.
|
||||
This <tt>RECORD</tt> contains all arguments with "out" direction
|
||||
including the return value of the C function (if there is one).
|
||||
If more than one argument is "out"
|
||||
then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
|
||||
but it is explicitly requested from the user to prevent mistakes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>constnumeric</td>
|
||||
<td><tt>%constnumeric(12) twelve;</tt> or
|
||||
<tt>%feature("constnumeric", "12") twelve;</tt></td>
|
||||
<td>This feature can be used to tell Modula-3's back-end of SWIG
|
||||
the value of an identifier.
|
||||
This is necessary in the cases
|
||||
where it was defined by a non-trivial C expression.
|
||||
This feature is used by the
|
||||
<tt>-generateconst</tt> <a href="#Modula3_commandline">option</a>.
|
||||
In future it may be generalized to other kind of values
|
||||
such as strings.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<H3><a name="Modula3_pragmas">31.5.2 Pragmas</a></H3>
|
||||
|
||||
|
||||
<table border summary="Modula-3 pragmas">
|
||||
<tr>
|
||||
<th>Pragma</th>
|
||||
<th>Example</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>unsafe</td>
|
||||
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
|
||||
<td>Mark the raw interface modules as <tt>UNSAFE</tt>.
|
||||
This will be necessary in many cases.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>library</td>
|
||||
<td><tt>%pragma(modula3) library="m3fftw";</tt></td>
|
||||
<td>Specifies the library name for the wrapper library to be created.
|
||||
It should be distinct from the name of the library to be wrapped.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<H2><a name="Modula3_remarks">31.6 Remarks</a></H2>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
|
||||
If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
|
||||
Modula files.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2243,7 +2243,7 @@ can be done using the <tt>EXTEND()</tt> macro as in:
|
|||
EXTEND(sp, 1); /* Extend the stack by 1 object */
|
||||
}
|
||||
$result = sv_newmortal();
|
||||
sv_setiv($target, (IV) *($1));
|
||||
sv_setiv($result, (IV) *($1));
|
||||
argvi++;
|
||||
}
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -51,12 +51,12 @@
|
|||
|
||||
<p>
|
||||
In this chapter, we discuss SWIG's support of PHP. SWIG currently supports
|
||||
generating wrappers for PHP7. Support for PHP5 was removed in SWIG 4.0.0
|
||||
and support for PHP4 was removed in SWIG 1.3.37.
|
||||
generating wrappers for PHP7 and PHP8. Support for PHP5 was removed in SWIG
|
||||
4.0.0 and support for PHP4 was removed in SWIG 1.3.37.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Currently any PHP7 release should work.
|
||||
Currently any PHP7 or PHP8 release should work.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -84,16 +84,21 @@ swig -php7 example.i
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
This will produce 3 files example_wrap.c, php_example.h and
|
||||
example.php. The first file, <tt>example_wrap.c</tt> contains all of
|
||||
This will produce 2 files: example_wrap.c and php_example.h.
|
||||
The first file, <tt>example_wrap.c</tt> contains all of
|
||||
the C code needed to build a PHP extension. The second file,
|
||||
<tt>php_example.h</tt> contains the header information needed if
|
||||
you wish to statically link the extension into the php interpreter.
|
||||
The third file,
|
||||
<tt>example.php</tt> can be included by PHP scripts. It attempts to
|
||||
dynamically load the extension and contains extra php code specified
|
||||
in the interface file. If wrapping C++ code with PHP classes, it will
|
||||
also contain PHP class wrappers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the interface file uses <tt>%pragma(php) include=</tt>... or
|
||||
<tt>%pragma(php) code=</tt>... then SWIG will also generate a third file,
|
||||
<tt>example.php</tt> to contain what these specify. In SWIG < 4.1.0,
|
||||
this third file was always generated as it defined the PHP classes, etc
|
||||
(but this is now done via C code in <tt>example_wrap.c</tt>) and also
|
||||
contained code to dynamically load the extension (but this used the
|
||||
PHP <tt>dl()</tt> function, which isn't recommended nowadays).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -139,22 +144,30 @@ least work for Linux though):
|
|||
|
||||
<p>
|
||||
To test the extension from a PHP script, you first need to tell PHP to
|
||||
load it. To do this, add a line like this to the <tt>[PHP]</tt> section of
|
||||
<tt>php.ini</tt>:
|
||||
load it. Assuming you're using PHP 7.2 or higher, the recommended (and
|
||||
simplest!) way to do this is to copy it to PHP's default extension directory
|
||||
and add a line like this to the <tt>[PHP]</tt> section of <tt>php.ini</tt>:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
extension=/path/to/modulename.so
|
||||
extension=modulename
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
If the module is in PHP's default extension directory, you can omit the path.
|
||||
PHP < 7.2 doesn't support loading by just the module name, so you need
|
||||
to specify the filename of the module to be specified, which varies
|
||||
between platforms. And for any PHP version, if the module is not in PHP's
|
||||
default extension directory, you also need to specify the path, for example:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
extension=/path/to/modulename.so
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
For some SAPIs (for example, the CLI SAPI) you can instead use the
|
||||
<a href="https://www.php.net/manual/en/function.dl.php">dl() function</a> to load
|
||||
an extension at run time, by adding a line like this to the start of each
|
||||
If you're using the PHP CLI SAPI it's possible (but not recommended) to use the
|
||||
<a href="https://www.php.net/manual/en/function.dl.php">dl() function</a> to
|
||||
load an extension at run time, by adding a line like this to the start of each
|
||||
PHP script which uses your extension:
|
||||
</p>
|
||||
|
||||
|
|
@ -163,23 +176,11 @@ PHP script which uses your extension:
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
But note that <tt>dl()</tt> isn't supported when running PHP through a
|
||||
webserver - you'll need to use <tt>extension</tt> in <tt>php.ini</tt> as
|
||||
described above.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The PHP module which SWIG generates will also attempt to do the <tt>dl()</tt>
|
||||
call for you if the extension isn't already loaded:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
This PHP module also defines the PHP classes for the wrapped API, so you'll
|
||||
almost certainly want to include it anyway.
|
||||
But to do this portably you need to take into account that pathnames and the
|
||||
filename extension vary by platform, and for security reasons PHP no longer
|
||||
supports <tt>dl()</tt> when running PHP through a webserver. Overall it's
|
||||
better to instead use <tt>extension</tt> in <tt>php.ini</tt> as described
|
||||
above.
|
||||
</p>
|
||||
|
||||
<H2><a name="Php_nn2">32.2 Basic PHP interface</a></H2>
|
||||
|
|
@ -219,24 +220,19 @@ you can access the constants in your PHP script like this,
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
|
||||
echo "PI = " . PI . "\n";
|
||||
|
||||
echo "E = " . E . "\n";
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
There's one peculiarity of how constants work in PHP which it is useful
|
||||
to note (this is not specific to SWIG though) - if you try to use an undeclared
|
||||
constant, PHP will emit a warning (or a notice in PHP 7.1 and earlier) and then
|
||||
expand the constant to a string version of the constant's name. Unfortunately
|
||||
it is easy to miss the warning message if you're using PHP in a webserver as
|
||||
it will probably end up in error.log or similar. Apparently this will throw
|
||||
an Error in a future version of PHP, but until then it's something to be
|
||||
aware of.
|
||||
There's one peculiarity of how constants work in PHP prior to PHP 8
|
||||
which it is useful to note (this is not specific to SWIG though) - if you try
|
||||
to use an undeclared constant, PHP will emit a warning (or a notice in PHP 7.1
|
||||
and earlier) and then expand the constant to a string version of the constant's
|
||||
name. Unfortunately it is easy to miss the warning message if you're using PHP
|
||||
in a webserver as it will probably end up in error.log or similar. PHP 8.0
|
||||
made this an error.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -256,8 +252,6 @@ accessed incorrectly in PHP,
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
include("example.php");
|
||||
|
||||
if(EASY_TO_MISPEL) {
|
||||
...
|
||||
} else {
|
||||
|
|
@ -298,7 +292,6 @@ is accessed as follows:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
print seki_get();
|
||||
seki_set( seki_get() * 2); # The C variable is now 4.
|
||||
print seki_get();
|
||||
|
|
@ -306,8 +299,10 @@ print seki_get();
|
|||
|
||||
<p>
|
||||
SWIG supports global variables of all C datatypes including pointers
|
||||
and complex objects. Additional types can be supported by using the
|
||||
<tt>varinit</tt> typemap.
|
||||
and complex objects. To support additional types, you just need to
|
||||
supply the standard <tt>in</tt> and <tt>out</tt> typemaps, which get
|
||||
used because of the wrapping as <tt>_get()</tt> and <tt>_set()</tt>
|
||||
functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -342,7 +337,6 @@ Will be accessed in PHP like this :
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
$a = foo(2);
|
||||
$b = bar(3.5, -1.5);
|
||||
$c = bar(3.5); # Use default argument for 2nd parameter
|
||||
|
|
@ -432,10 +426,12 @@ taking the integer argument.
|
|||
|
||||
<H3><a name="Php_nn2_5">32.2.5 Pointers and References</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Pointers to C/C++ objects are represented
|
||||
as PHP resources, rather like MySQL connection handles.
|
||||
Since SWIG 4.1.0, SWIG wraps C/C++ classes directly with PHP objects.
|
||||
Pointers to other types are also wrapped as PHP objects - mostly this is an
|
||||
implementation detail, but it's visible from PHP via <tt>is_object()</tt> and
|
||||
similar. In earlier SWIG versions, PHP resources were used to wrap both
|
||||
classes and pointers to other types.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -467,8 +463,6 @@ This will result in the following usage in PHP:
|
|||
<div class="code"><pre>
|
||||
<?php
|
||||
|
||||
include("example.php");
|
||||
|
||||
$in1=copy_intp(3);
|
||||
$in2=copy_intp(5);
|
||||
$result=new_intp();
|
||||
|
|
@ -476,7 +470,6 @@ $result=new_intp();
|
|||
add( $in1, $in2, $result );
|
||||
|
||||
echo "The sum " . intp_value($in1) . " + " . intp_value($in2) . " = " . intp_value( $result) . "\n";
|
||||
?>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -501,14 +494,11 @@ This will result in the following usage in PHP:
|
|||
<div class="code"><pre>
|
||||
<?php
|
||||
|
||||
include("example.php");
|
||||
|
||||
$in1 = 3;
|
||||
$in2 = 5;
|
||||
$result= add($in1, $in2); # Note using variables for the input is unnecessary.
|
||||
|
||||
echo "The sum $in1 + $in2 = $result\n";
|
||||
?>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -539,15 +529,12 @@ This will result in the following usage in PHP:
|
|||
<div class="code"><pre>
|
||||
<?php
|
||||
|
||||
include("example.php");
|
||||
|
||||
$in1 = 3;
|
||||
$in2 = 5;
|
||||
$result = 0;
|
||||
add($in1, $in2, $result);
|
||||
|
||||
echo "The sum $in1 + $in2 = $result\n";
|
||||
?>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -572,11 +559,16 @@ variable, or assigning <tt>NULL</tt> to a variable.
|
|||
|
||||
|
||||
<p>
|
||||
SWIG defaults to wrapping C++ structs and classes with PHP classes - this
|
||||
is done by generating a PHP wrapper script which defines proxy classes
|
||||
which calls a set of flat functions which actually wrap the C++ class.
|
||||
You can disable this wrapper layer by passing the command-line option
|
||||
"-noproxy" in which case you'll just get the flat functions.
|
||||
SWIG defaults to wrapping C++ structs and classes with PHP classes.
|
||||
Since SWIG 4.1.0, this is done entirely via PHP's C API - earlier SWIG
|
||||
versions generated a PHP wrapper script which defined proxy classes
|
||||
which called a set of flat functions which actually wrapped the C++ class.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you don't want the class wrappers, you can pass the command-line option
|
||||
"-noproxy" in which case you'll get C++ classes wrapped as flat functions
|
||||
as described below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -605,7 +597,6 @@ Would be used in the following way from PHP:
|
|||
|
||||
<div class="code"><pre>
|
||||
<?php
|
||||
require "vector.php";
|
||||
|
||||
$v = new Vector();
|
||||
$v->x = 3;
|
||||
|
|
@ -622,7 +613,6 @@ Would be used in the following way from PHP:
|
|||
$c->im = 0;
|
||||
|
||||
# $c destructor called when $c goes out of scope.
|
||||
?>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -667,8 +657,8 @@ constructor to execute.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Because PHP uses reference counting to manage resources, simple
|
||||
assignment of one variable to another such as:
|
||||
Because PHP uses reference counting, simple assignment of one variable to
|
||||
another such as:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
@ -721,8 +711,6 @@ would be accessed in PHP as,
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
|
||||
echo "There have now been " . Ko::threats() . " threats\n";
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -756,7 +744,6 @@ class Ko {
|
|||
|
||||
would be executed in PHP as,
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
Ko::threats();
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -783,9 +770,8 @@ If there are multiple interfaces, just list them separated by commas.
|
|||
|
||||
|
||||
<p>
|
||||
To place PHP code in the generated "example.php" file one can use the
|
||||
<b>code</b> pragma. The code is inserted after loading the shared
|
||||
object.
|
||||
You can get SWIG to generate an "example.php" file by specifying
|
||||
the code to put in it using the <b>code</b> pragma.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
@ -883,7 +869,7 @@ into the request init (PHP_RINIT_FUNCTION) and request shutdown (PHP_RSHUTDOWN_F
|
|||
Proxy classes provide a more natural, object-oriented way to access
|
||||
extension classes. As described above, each proxy instance has an
|
||||
associated C++ instance, and method calls to the proxy are passed to the
|
||||
C++ instance transparently via C wrapper functions.
|
||||
C++ instance transparently.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -989,8 +975,6 @@ then at the PHP side you can define
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
require("mymodule.php");
|
||||
|
||||
class MyFoo extends Foo {
|
||||
function one() {
|
||||
print "one from php\n";
|
||||
|
|
@ -1012,8 +996,8 @@ that derives from both the class in question and a special
|
|||
<tt>Swig::Director</tt> class. These new classes, referred to as director
|
||||
classes, can be loosely thought of as the C++ equivalent of the PHP
|
||||
proxy classes. The director classes store a pointer to their underlying
|
||||
PHP object. Indeed, this is quite similar to the "_cPtr" and "thisown"
|
||||
members of the PHP proxy classes.
|
||||
PHP object. Indeed, this is quite similar to <tt>struct swig_object_wrapper</tt>
|
||||
which is used to implement the PHP proxy classes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -1068,12 +1052,12 @@ infinite loop.
|
|||
<p>
|
||||
One more point needs to be made about the relationship between director
|
||||
classes and proxy classes. When a proxy class instance is created in
|
||||
PHP, SWIG creates an instance of the original C++ class and assigns it
|
||||
to <tt>->_cPtr</tt>. This is exactly what happens without directors
|
||||
and is true even if directors are enabled for the particular class in
|
||||
question. When a class <i>derived</i> from a proxy class is created,
|
||||
however, SWIG then creates an instance of the corresponding C++ director
|
||||
class. The reason for this difference is that user-defined subclasses
|
||||
PHP, SWIG creates an instance of the original C++ class and stores it
|
||||
in the <tt>struct swig_object_wrapper</tt>. This is true whether or not
|
||||
directors are enabled for the particular class in question. However
|
||||
when a class <i>derived</i> from a proxy class is created, SWIG instead
|
||||
creates an instance of the corresponding C++ director class.
|
||||
The reason for this difference is that user-defined subclasses
|
||||
may override or extend methods of the original class, so the director
|
||||
class is needed to route calls to these methods correctly. For
|
||||
unmodified proxy classes, all methods are ultimately implemented in C++
|
||||
|
|
@ -1161,13 +1145,32 @@ should suffice in most cases:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error == FAILURE) {
|
||||
#if SWIG_VERSION >= 0x040100
|
||||
if ($error != NULL)
|
||||
#else
|
||||
if ($error == FAILURE)
|
||||
#endif
|
||||
{
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If you only need to support SWIG >= 4.1.0, you can just use the
|
||||
<tt>($error != NULL)</tt> condition.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In SWIG 4.1.0, <tt>$error</tt> was changed in the SWIG/PHP director
|
||||
implementation to make it work more like how it does for other languages.
|
||||
Previously, <tt>$error</tt> didn't actually indicate an exception, but instead
|
||||
was only set to <tt>FAILURE</tt> if there was a problem calling the PHP method.
|
||||
Now <tt>$error</tt> indicates if the PHP method threw a PHP exception, and
|
||||
directorout typemaps for PHP no longer need to be gated by <tt>if (EG(exception))</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This code will check the PHP error state after each method call from a
|
||||
director into PHP, and throw a C++ exception if an error occurred. This
|
||||
|
|
|
|||
|
|
@ -1,246 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG and Pike</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
<H1><a name="Pike">37 SWIG and Pike</a></H1>
|
||||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#Pike_nn2">Preliminaries</a>
|
||||
<ul>
|
||||
<li><a href="#Pike_nn3">Running SWIG</a>
|
||||
<li><a href="#Pike_nn4">Getting the right header files</a>
|
||||
<li><a href="#Pike_nn5">Using your module</a>
|
||||
</ul>
|
||||
<li><a href="#Pike_nn6">Basic C/C++ Mapping</a>
|
||||
<ul>
|
||||
<li><a href="#Pike_nn7">Modules</a>
|
||||
<li><a href="#Pike_nn8">Functions</a>
|
||||
<li><a href="#Pike_nn9">Global variables</a>
|
||||
<li><a href="#Pike_nn10">Constants and enumerated types</a>
|
||||
<li><a href="#Pike_nn11">Constructors and Destructors</a>
|
||||
<li><a href="#Pike_nn12">Static Members</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
This chapter describes SWIG support for Pike. As of this writing, the
|
||||
SWIG Pike module is still under development and is not considered
|
||||
ready for prime time. The Pike module is being developed against the
|
||||
Pike 7.4.10 release and may not be compatible with previous versions
|
||||
of Pike.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This chapter covers most SWIG features, but certain low-level details
|
||||
are covered in less depth than in earlier chapters. At the very
|
||||
least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
|
||||
chapter.<br>
|
||||
</p>
|
||||
|
||||
<H2><a name="Pike_nn2">37.1 Preliminaries</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Pike_nn3">37.1.1 Running SWIG</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Suppose that you defined a SWIG module such as the following:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>%module example<br><br>%{<br>#include "example.h"<br>%}<br><br>int fact(int n);<br></pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
To build a C extension module for Pike, run SWIG using the <tt>-pike</tt> option :
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>$ <b>swig -pike example.i</b><br></pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If you're building a C++ extension, be sure to add the <tt>-c++</tt> option:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>$ <b>swig -c++ -pike example.i</b><br></pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This creates a single source file named <tt>example_wrap.c</tt> (or <tt>example_wrap.cxx</tt>, if you
|
||||
ran SWIG with the <tt>-c++</tt> option).
|
||||
The SWIG-generated source file contains the low-level wrappers that need
|
||||
to be compiled and linked with the rest of your C/C++ application to
|
||||
create an extension module.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The name of the wrapper file is derived from the name of the input
|
||||
file. For example, if the input file is <tt>example.i</tt>, the name
|
||||
of the wrapper file is <tt>example_wrap.c</tt>. To change this, you
|
||||
can use the <tt>-o</tt> option:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
|
||||
</div>
|
||||
<H3><a name="Pike_nn4">37.1.2 Getting the right header files</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
In order to compile the C/C++ wrappers, the compiler needs to know the
|
||||
path to the Pike header files. These files are usually contained in a
|
||||
directory such as
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>/usr/local/pike/7.4.10/include/pike<br></pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
There doesn't seem to be any way to get Pike itself to reveal the
|
||||
location of these files, so you may need to hunt around for them.
|
||||
You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt>
|
||||
and so on.
|
||||
</p>
|
||||
|
||||
<H3><a name="Pike_nn5">37.1.3 Using your module</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
To use your module, simply use Pike's <tt>import</tt> statement:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
$ <b>pike</b>
|
||||
Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
|
||||
> <b>import example;</b>
|
||||
> <b>fact(4);</b>
|
||||
(1) Result: 24
|
||||
</pre></div>
|
||||
|
||||
<H2><a name="Pike_nn6">37.2 Basic C/C++ Mapping</a></H2>
|
||||
|
||||
|
||||
<H3><a name="Pike_nn7">37.2.1 Modules</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
All of the code for a given SWIG module is wrapped into a single Pike
|
||||
module. Since the name of the shared library that implements your
|
||||
module ultimately determines the module's name (as far as Pike is
|
||||
concerned), SWIG's <tt>%module</tt> directive doesn't really have any
|
||||
significance.
|
||||
</p>
|
||||
|
||||
<H3><a name="Pike_nn8">37.2.2 Functions</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Global functions are wrapped as new Pike built-in functions. For
|
||||
example,
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
int fact(int n);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
creates a new built-in function <tt>example.fact(n)</tt> that works
|
||||
exactly as you'd expect it to:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
> <b>import example;</b>
|
||||
> <b>fact(4);</b>
|
||||
(1) Result: 24
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Pike_nn9">37.2.3 Global variables</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Global variables are currently wrapped as a pair of functions, one to get
|
||||
the current value of the variable and another to set it. For example, the
|
||||
declaration
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
double Foo;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
> <b>import example;</b>
|
||||
> <b>Foo_get();</b>
|
||||
(1) Result: 3.000000
|
||||
> <b>Foo_set(3.14159);</b>
|
||||
(2) Result: 0
|
||||
> <b>Foo_get();</b>
|
||||
(3) Result: 3.141590
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Pike_nn10">37.2.4 Constants and enumerated types</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Enumerated types in C/C++ declarations are wrapped as Pike constants,
|
||||
not as Pike enums.
|
||||
</p>
|
||||
|
||||
<H3><a name="Pike_nn11">37.2.5 Constructors and Destructors</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Constructors are wrapped as <tt>create()</tt> methods, and destructors are
|
||||
wrapped as <tt>destroy()</tt> methods, for Pike classes.
|
||||
</p>
|
||||
|
||||
<H3><a name="Pike_nn12">37.2.6 Static Members</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
Since Pike doesn't support static methods or data for Pike classes, static
|
||||
member functions in your C++ classes are wrapped as regular functions and
|
||||
static member variables are wrapped as pairs of functions (one to get the
|
||||
value of the static member variable, and another to set it). The names of
|
||||
these functions are prepended with the name of the class.
|
||||
For example, given this C++ class declaration:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class Shape
|
||||
{
|
||||
public:
|
||||
static void print();
|
||||
static int nshapes;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
SWIG will generate a <tt>Shape_print()</tt> method that invokes the static
|
||||
<tt>Shape::print()</tt> member function, as well as a pair of methods,
|
||||
<tt>Shape_nshapes_get()</tt> and <tt>Shape_nshapes_set()</tt>, to get and set
|
||||
the value of <tt>Shape::nshapes</tt>.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -123,7 +123,7 @@ SWIGOCAML Defined when using OCaml
|
|||
SWIGOCTAVE Defined when using Octave
|
||||
SWIGPERL Defined when using Perl
|
||||
SWIGPHP Defined when using PHP (any version)
|
||||
SWIGPHP7 Defined when using PHP7
|
||||
SWIGPHP7 Defined when using PHP 7 or later (with a compatible C API)
|
||||
SWIGPYTHON Defined when using Python
|
||||
SWIGR Defined when using R
|
||||
SWIGRUBY Defined when using Ruby
|
||||
|
|
|
|||
|
|
@ -1608,7 +1608,7 @@ public:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
In Python, the static member can be access in three different ways:
|
||||
In Python, the static member can be accessed in three different ways:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
|
|
@ -1616,7 +1616,7 @@ In Python, the static member can be access in three different ways:
|
|||
>>> example.Spam_foo() # Spam::foo()
|
||||
>>> s = example.Spam()
|
||||
>>> s.foo() # Spam::foo() via an instance
|
||||
>>> example.Spam.foo() # Spam::foo(). Python-2.2 only
|
||||
>>> example.Spam.foo() # Spam::foo() using Python-2.2 and later
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1627,16 +1627,31 @@ last technique is only available in Python-2.2 and later versions.
|
|||
|
||||
<p>
|
||||
Static member variables are currently accessed as global variables. This means,
|
||||
they are accessed through <tt>cvar</tt> like this:
|
||||
they are accessed through <tt>cvar</tt> or via an instance property:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> print example.cvar.Spam_bar
|
||||
>>> example.cvar.Spam_bar # Spam::bar
|
||||
7
|
||||
>>> s = example.Spam()
|
||||
>>> s.bar # Spam::bar via an instance property
|
||||
7
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The <tt>-builtin</tt> option uses a metaclass to additionally provide access as follows:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> example.Spam.bar # Spam::bar using -builtin option only
|
||||
7
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<H3><a name="Python_nn21">33.3.8 C++ inheritance</a></H3>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ slices)
|
|||
<p>
|
||||
Wrapping of C++ classes for R works quite well. R has a special
|
||||
type, known as an external reference, that can be used as a pointer
|
||||
to arbitary things, including C++ classes. The proxy layers generated
|
||||
to arbitrary things, including C++ classes. The proxy layers generated
|
||||
for other classes are not required.
|
||||
</p>
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ v2$Axles
|
|||
[1] 4
|
||||
v1$Available
|
||||
[1] FALSE
|
||||
# Set availabilty
|
||||
# Set availability
|
||||
v1$Available <- TRUE
|
||||
v1$Available
|
||||
[1] TRUE
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ Supported Target Language Options
|
|||
-lua - Generate Lua wrappers
|
||||
-octave - Generate Octave wrappers
|
||||
-perl5 - Generate Perl 5 wrappers
|
||||
-php7 - Generate PHP 7 wrappers
|
||||
-php7 - Generate PHP 7 or later wrappers
|
||||
-python - Generate Python wrappers
|
||||
-r - Generate R (aka GNU S) wrappers
|
||||
-ruby - Generate Ruby wrappers
|
||||
|
|
@ -2020,7 +2020,7 @@ and a more descriptive one, but the two functions are otherwise equivalent:
|
|||
<tr>
|
||||
<td><span style="white-space: nowrap;"><tt>regex:/pattern/subst/</tt></span></td>
|
||||
<td>String after (Perl-like) regex substitution operation. This function
|
||||
allows to apply arbitrary regular expressions to the identifier names. The
|
||||
allows applying arbitrary regular expressions to the identifier names. The
|
||||
<i>pattern</i> part is a regular expression in Perl syntax (as supported
|
||||
by the <a href="http://www.pcre.org/">Perl Compatible Regular Expressions (PCRE)</a>)
|
||||
library and the <i>subst</i> string
|
||||
|
|
|
|||
|
|
@ -3632,7 +3632,7 @@ Alternatively, you could expand the constructor template in selected instantiati
|
|||
|
||||
// Create default and conversion constructors
|
||||
%extend pair<double, double> {
|
||||
%template(paird) pair<double, dobule>; // Default constructor
|
||||
%template(paird) pair<double, double>; // Default constructor
|
||||
%template(pairc) pair<int, int>; // Conversion constructor
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -3647,7 +3647,7 @@ instead:
|
|||
<pre>
|
||||
// Create default and conversion constructors
|
||||
%extend pair<double, double> {
|
||||
%template(pair) pair<double, dobule>; // Default constructor
|
||||
%template(pair) pair<double, double>; // Default constructor
|
||||
%template(pair) pair<int, int>; // Conversion constructor
|
||||
};
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ example.i(4) : Syntax error in input(1).
|
|||
<li>401. Nothing known about class 'name'. Ignored.
|
||||
<li>402. Base class 'name' is incomplete.
|
||||
<li>403. Class 'name' might be abstract.
|
||||
<li>450. Deprecated typemap feature ($source/$target).
|
||||
<li>450. Reserved
|
||||
<li>451. Setting const char * variable may leak memory.
|
||||
<li>452. Reserved
|
||||
<li>453. Can't apply (pattern). No typemaps are defined.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<li><a href="#Windows_swig_exe">Building swig.exe on Windows</a>
|
||||
<ul>
|
||||
<li><a href="#Windows_cmake">Building swig.exe using CMake</a>
|
||||
<li><a href="#Windows_mingw_msys">Building swig.exe using MSYS2</a>
|
||||
<li><a href="#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
|
||||
<li><a href="#Windows_cygwin">Building swig.exe using Cygwin</a>
|
||||
</ul>
|
||||
|
|
@ -250,7 +251,8 @@ For fully working build steps always check the Continuous Integration setups cur
|
|||
and save to a folder e.g. C:\Tools\Bison
|
||||
</li>
|
||||
<li>
|
||||
Install PCRE using Nuget using the following command: <pre>C:\Tools\nuget install pcre -Version 8.33.0.1 -OutputDirectory C:\Tools\pcre</pre>
|
||||
Install PCRE using Nuget using the following command: <pre>C:\Tools\nuget install pcre -Version 8.33.0.1 -OutputDirectory C:\Tools\pcre</pre>.
|
||||
Alternatively, use <tt>WITH_PCRE</tt> option to disable PCRE support if you are sure not to need it.
|
||||
</li>
|
||||
<li>
|
||||
We will also need the SWIG source code. Either download a zipped archive from GitHub, or if git is installed clone the latest codebase
|
||||
|
|
@ -296,7 +298,59 @@ swig.exe -help
|
|||
<pre>-python -c++ -o C:\Temp\doxygen_parsing.cpp C:\swig\Examples\test-suite\doxygen_parsing.i</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Windows_mingw_msys">3.3.1.2 Building swig.exe using MinGW and MSYS</a></H4>
|
||||
<H4><a name="Windows_mingw_msys">3.3.1.2 Building swig.exe using MSYS2</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
Download and install MSYS2 from <a href="https://www.msys2.org/">www.msys2.org</a> (tested with version msys2-x86_64-20201109).
|
||||
Launch the MSYS2 shell.
|
||||
</p>
|
||||
<p>
|
||||
Install the packages needed to build swig:<br>
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
pacman -S git autoconf automake bison gcc make pcre-devel
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Clone the repository to /usr/src/:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
mkdir /usr/src/
|
||||
cd /usr/src/
|
||||
git clone https://github.com/swig/swig.git
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Configure and build:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
cd /usr/src/swig
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Finally you may also want to install SWIG:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
make install
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Windows_mingw_msys">3.3.1.3 Building swig.exe using MinGW and MSYS</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -414,7 +468,7 @@ make
|
|||
</ol>
|
||||
|
||||
|
||||
<H4><a name="Windows_cygwin">3.3.1.3 Building swig.exe using Cygwin</a></H4>
|
||||
<H4><a name="Windows_cygwin">3.3.1.4 Building swig.exe using Cygwin</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ TCL_SO = @TCL_SO@
|
|||
TCLLDSHARED = @TCLLDSHARED@
|
||||
TCLCXXSHARED = @TCLCXXSHARED@
|
||||
TCL_SCRIPT = $(SRCDIR)$(RUNME).tcl
|
||||
TCL_LINK = @TCLLINK@
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Build a new version of the tclsh shell
|
||||
|
|
@ -187,7 +188,7 @@ tclsh_cpp: $(SRCDIR_SRCS)
|
|||
tcl: $(SRCDIR_SRCS)
|
||||
$(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE)
|
||||
$(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO)
|
||||
$(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Build a Tcl7.5 dynamic loadable module for C++
|
||||
|
|
@ -196,7 +197,7 @@ tcl: $(SRCDIR_SRCS)
|
|||
tcl_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE)
|
||||
$(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO)
|
||||
$(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Run Tcl example
|
||||
|
|
@ -1045,20 +1046,21 @@ ruby_clean:
|
|||
rm -f *.@OBJEXT@ *$(RUBY_SO)
|
||||
|
||||
##################################################################
|
||||
##### PHP7 ######
|
||||
##### PHP ######
|
||||
##################################################################
|
||||
|
||||
PHP = @PHP@
|
||||
PHP_INCLUDE = @PHPINC@
|
||||
PHP_SO = @PHP_SO@
|
||||
PHP_SCRIPT = $(SRCDIR)$(RUNME).php
|
||||
PHP_EXTENSION = example$(PHP_SO)
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Build a PHP dynamically loadable module (C)
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
php: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php7 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -php $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
|
||||
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
|
||||
|
||||
|
|
@ -1067,7 +1069,7 @@ php: $(SRCDIR_SRCS)
|
|||
# --------------------------------------------------------------------
|
||||
|
||||
php_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIG) -php7 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(SWIG) -php -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
|
||||
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
|
||||
|
||||
|
|
@ -1076,7 +1078,7 @@ php_cpp: $(SRCDIR_SRCS)
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
php_run:
|
||||
$(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off -d display_errors=stderr $(PHP_SCRIPT) $(RUNPIPE)
|
||||
$(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});include($$argv[1]);' $(PHP_SCRIPT) $(RUNPIPE)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Version display
|
||||
|
|
@ -1248,46 +1250,6 @@ lua_clean:
|
|||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *$(LUA_SO)
|
||||
|
||||
##################################################################
|
||||
##### ALLEGRO CL ######
|
||||
##################################################################
|
||||
|
||||
ALLEGROCL = @ALLEGROCLBIN@
|
||||
ALLEGROCL_SCRIPT=$(RUNME).lisp
|
||||
|
||||
allegrocl: $(SRCDIR_SRCS)
|
||||
$(SWIG) -allegrocl -cwrap $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
|
||||
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCDIR_SRCS)
|
||||
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
allegrocl_cpp: $(SRCDIR_SRCS)
|
||||
$(SWIG) -c++ -allegrocl $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
|
||||
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES)
|
||||
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Run ALLEGRO CL example
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
allegrocl_run:
|
||||
$(RUNTOOL) $(ALLEGROCL) -batch -s $(ALLEGROCL_SCRIPT) $(RUNPIPE)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Version display
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
allegrocl_version:
|
||||
$(ALLEGROCL) --version
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Cleaning the ALLEGRO CL examples
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
allegrocl_clean:
|
||||
rm -f *_wrap* *~ .~*
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@
|
||||
|
||||
##################################################################
|
||||
##### CFFI ######
|
||||
##################################################################
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
This directory contains examples for CHICKEN.
|
||||
|
||||
class -- illustrates the proxy class C++ interface
|
||||
constants -- handling #define and %constant literals
|
||||
egg -- examples of building chicken extension libraries
|
||||
multimap -- typemaps with multiple sub-types
|
||||
overload -- C++ function overloading
|
||||
simple -- the simple example from the user manual
|
||||
zlib -- a wrapping of the zlib compression library
|
||||
|
||||
You should be able to run make in each of the examples. By default, a shared
|
||||
library will be built. Run make check to execute the test.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
# see top-level Makefile.in
|
||||
class
|
||||
constants
|
||||
multimap
|
||||
overload
|
||||
simple
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
INTERFACE = example.i
|
||||
SRCS =
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = class
|
||||
INCLUDE =
|
||||
SWIGOPT =
|
||||
VARIANT =
|
||||
|
||||
# uncomment the following lines to build a static exe (only pick one of the CHICKEN_MAIN lines)
|
||||
#CHICKEN_MAIN = runme-lowlevel.scm
|
||||
#CHICKEN_MAIN = runme-tinyclos.scm
|
||||
#VARIANT = _static
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CHICKEN_SCRIPT='runme-lowlevel.scm' chicken_run
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CHICKEN_SCRIPT='runme-tinyclos.scm' chicken_run
|
||||
|
||||
build: $(TARGET) $(TARGET)_proxy
|
||||
|
||||
$(TARGET): $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
|
||||
|
||||
$(TARGET)_proxy: $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT) -proxy' TARGET='$(TARGET)_proxy' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
|
||||
rm -f example.scm
|
||||
rm -f $(TARGET)
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
/* Move the shape to a new location */
|
||||
void Shape::move(double dx, double dy) {
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
int Shape::nshapes = 0;
|
||||
|
||||
double Circle::area() {
|
||||
return M_PI*radius*radius;
|
||||
}
|
||||
|
||||
double Circle::perimeter() {
|
||||
return 2*M_PI*radius;
|
||||
}
|
||||
|
||||
double Square::area() {
|
||||
return width*width;
|
||||
}
|
||||
|
||||
double Square::perimeter() {
|
||||
return 4*width;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
nshapes++;
|
||||
}
|
||||
virtual ~Shape() {
|
||||
nshapes--;
|
||||
}
|
||||
double x, y;
|
||||
void move(double dx, double dy);
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
static int nshapes;
|
||||
|
||||
enum SomeEnum {
|
||||
First = 0,
|
||||
Second,
|
||||
Third,
|
||||
Last = 1000
|
||||
};
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
private:
|
||||
double radius;
|
||||
public:
|
||||
Circle(double r) : radius(r) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
|
||||
class Square : public Shape {
|
||||
private:
|
||||
double width;
|
||||
public:
|
||||
Square(double w) : width(w) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
;; This file illustrates the low-level C++ interface generated
|
||||
;; by SWIG.
|
||||
|
||||
(load-library 'example "class.so")
|
||||
(declare (uses example))
|
||||
|
||||
;; ----- Object creation -----
|
||||
|
||||
(display "Creating some objects:\n")
|
||||
(define c (new-Circle 10.0))
|
||||
(display " Created circle ")
|
||||
(display c)
|
||||
(display "\n")
|
||||
(define s (new-Square 10.0))
|
||||
(display " Created square ")
|
||||
(display s)
|
||||
(display "\n")
|
||||
|
||||
;; ----- Access a static member -----
|
||||
|
||||
(display "\nA total of ")
|
||||
(display (Shape-nshapes))
|
||||
(display " shapes were created\n")
|
||||
|
||||
;; ----- Member data access -----
|
||||
|
||||
;; Set the location of the object
|
||||
|
||||
(Shape-x-set c 20.0)
|
||||
(Shape-y-set c 30.0)
|
||||
|
||||
(Shape-x-set s -10.0)
|
||||
(Shape-y-set s 5.0)
|
||||
|
||||
(display "\nHere is their current position:\n")
|
||||
(display " Circle = (")
|
||||
(display (Shape-x-get c))
|
||||
(display ", ")
|
||||
(display (Shape-y-get c))
|
||||
(display ")\n")
|
||||
(display " Square = (")
|
||||
(display (Shape-x-get s))
|
||||
(display ", ")
|
||||
(display (Shape-y-get s))
|
||||
(display ")\n")
|
||||
|
||||
;; ----- Call some methods -----
|
||||
|
||||
(display "\nHere are some properties of the shapes:\n")
|
||||
(let
|
||||
((disp (lambda (o)
|
||||
(display " ")
|
||||
(display o)
|
||||
(display "\n")
|
||||
(display " area = ")
|
||||
(display (Shape-area o))
|
||||
(display "\n")
|
||||
(display " perimeter = ")
|
||||
(display (Shape-perimeter o))
|
||||
(display "\n"))))
|
||||
(disp c)
|
||||
(disp s))
|
||||
|
||||
(display "\nGuess I'll clean up now\n")
|
||||
|
||||
;; Note: this invokes the virtual destructor
|
||||
(set! c #f)
|
||||
(set! s #f)
|
||||
(gc #t)
|
||||
|
||||
(set! s 3)
|
||||
(display (Shape-nshapes))
|
||||
(display " shapes remain\n")
|
||||
(display "Goodbye\n")
|
||||
|
||||
(exit)
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
;; This file illustrates the proxy C++ interface generated
|
||||
;; by SWIG.
|
||||
|
||||
(load-library 'example "class_proxy.so")
|
||||
(declare (uses example))
|
||||
(declare (uses tinyclos))
|
||||
|
||||
;; ----- Object creation -----
|
||||
|
||||
(display "Creating some objects:\n")
|
||||
(define c (make <Circle> 10.0))
|
||||
(display " Created circle ")
|
||||
(display c)
|
||||
(display "\n")
|
||||
(define s (make <Square> 10.0))
|
||||
(display " Created square ")
|
||||
(display s)
|
||||
(display "\n")
|
||||
|
||||
;; ----- Access a static member -----
|
||||
|
||||
(display "\nA total of ")
|
||||
(display (Shape-nshapes))
|
||||
(display " shapes were created\n")
|
||||
|
||||
;; ----- Member data access -----
|
||||
|
||||
;; Set the location of the object
|
||||
|
||||
(slot-set! c 'x 20.0)
|
||||
(slot-set! c 'y 30.0)
|
||||
|
||||
(slot-set! s 'x -10.0)
|
||||
(slot-set! s 'y 5.0)
|
||||
|
||||
(display "\nHere is their current position:\n")
|
||||
(display " Circle = (")
|
||||
(display (slot-ref c 'x))
|
||||
(display ", ")
|
||||
(display (slot-ref c 'y))
|
||||
(display ")\n")
|
||||
(display " Square = (")
|
||||
(display (slot-ref s 'x))
|
||||
(display ", ")
|
||||
(display (slot-ref s 'y))
|
||||
(display ")\n")
|
||||
|
||||
;; ----- Call some methods -----
|
||||
|
||||
(display "\nHere are some properties of the shapes:\n")
|
||||
(let
|
||||
((disp (lambda (o)
|
||||
(display " ")
|
||||
(display o)
|
||||
(display "\n")
|
||||
(display " area = ")
|
||||
(display (area o))
|
||||
(display "\n")
|
||||
(display " perimeter = ")
|
||||
(display (perimeter o))
|
||||
(display "\n"))))
|
||||
(disp c)
|
||||
(disp s))
|
||||
|
||||
(display "\nGuess I'll clean up now\n")
|
||||
|
||||
;; Note: Invoke the virtual destructors by forcing garbage collection
|
||||
(set! c 77)
|
||||
(set! s 88)
|
||||
(gc #t)
|
||||
|
||||
(display (Shape-nshapes))
|
||||
(display " shapes remain\n")
|
||||
(display "Goodbye\n")
|
||||
|
||||
(exit)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
INTERFACE = example.i
|
||||
SRCS =
|
||||
CXXSRCS =
|
||||
TARGET = constants
|
||||
INCLUDE =
|
||||
SWIGOPT =
|
||||
VARIANT =
|
||||
|
||||
# uncomment the following two lines to build a static exe
|
||||
#CHICKEN_MAIN = runme.scm
|
||||
#VARIANT = _static
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
|
||||
|
||||
build: $(TARGET)
|
||||
|
||||
$(TARGET): $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
|
||||
rm -f example.scm
|
||||
rm -f $(TARGET)
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
/* A few preprocessor macros */
|
||||
|
||||
#define ICONST 42
|
||||
#define FCONST 2.1828
|
||||
#define CCONST 'x'
|
||||
#define CCONST2 '\n'
|
||||
#define SCONST "Hello World"
|
||||
#define SCONST2 "\"Hello World\""
|
||||
|
||||
/* This should work just fine */
|
||||
#define EXPR ICONST + 3*(FCONST)
|
||||
|
||||
/* This shouldn't do anything */
|
||||
#define EXTERN extern
|
||||
|
||||
/* Neither should this (BAR isn't defined) */
|
||||
#define FOO (ICONST + BAR)
|
||||
|
||||
/* The following directives also produce constants. Remember that
|
||||
CHICKEN is normally case-insensitive, so don't rely on differing
|
||||
case to differentiate variable names */
|
||||
|
||||
%constant int iconstX = 37;
|
||||
%constant double fconstX = 3.14;
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
;; feel free to uncomment and comment sections
|
||||
|
||||
(load-library 'example "./constants.so")
|
||||
|
||||
(display "starting test ... you will see 'finished' if successful.\n")
|
||||
(or (= (ICONST) 42) (exit 1))
|
||||
(or (< (abs (- (FCONST) 2.1828)) 0.00001) (exit 1))
|
||||
(or (char=? (CCONST) #\x) (exit 1))
|
||||
(or (char=? (CCONST2) #\newline) (exit 1))
|
||||
(or (string=? (SCONST) "Hello World") (exit 1))
|
||||
(or (string=? (SCONST2) "\"Hello World\"") (exit 1))
|
||||
(or (< (abs (- (EXPR) (+ (ICONST) (* 3 (FCONST))))) 0.00001) (exit 1))
|
||||
(or (= (iconstX) 37) (exit 1))
|
||||
(or (< (abs (- (fconstX) 3.14)) 0.00001) (exit 1))
|
||||
(display "finished test.\n")
|
||||
(exit 0)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
|
||||
check: build
|
||||
cd eggs/install && csi ../../test.scm
|
||||
|
||||
build: single multi
|
||||
|
||||
# This creates an egg which contains only the single module. Any additional implementation files
|
||||
# that implement the interface being wrapped should also be added to this egg
|
||||
single: single_wrap.cxx
|
||||
mkdir -p eggs
|
||||
tar czf eggs/single.egg single.setup single.scm single_wrap.cxx
|
||||
rm -f single.scm single_wrap.cxx
|
||||
|
||||
# compile the single module with -nounit
|
||||
single_wrap.cxx: single.i
|
||||
$(SWIGEXE) -chicken -c++ -proxy -nounit single.i
|
||||
|
||||
# Now build both mod1 and mod2 into a single egg
|
||||
multi: mod1_wrap.cxx mod2_wrap.cxx
|
||||
mkdir -p eggs
|
||||
tar czf eggs/multi.egg multi.setup multi_init.scm mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx
|
||||
rm -f mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx
|
||||
|
||||
mod1_wrap.cxx: mod1.i
|
||||
$(SWIGEXE) -chicken -c++ -proxy mod1.i
|
||||
|
||||
mod2_wrap.cxx: mod2.i
|
||||
$(SWIGEXE) -chicken -c++ -proxy mod2.i
|
||||
|
||||
clean:
|
||||
rm -rf eggs
|
||||
|
||||
# this part is for testing...
|
||||
setup:
|
||||
cd eggs && \
|
||||
mkdir -p install && \
|
||||
chicken-setup -repository `pwd`/install single.egg && \
|
||||
chicken-setup -repository `pwd`/install multi.egg
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
These examples show how to build a chicken extension module in the form of an
|
||||
egg. There are two eggs that get built, single.egg which contains a single
|
||||
module which is built with -nounit and multi.egg, which contains two modules
|
||||
mod1 and mod2. These are built normally, and multi_init.scm loads them both.
|
||||
Read section "17.4.2 Building chicken extension libraries" in the manual
|
||||
for a description of these two techniques.
|
||||
|
||||
To build:
|
||||
|
||||
$ make
|
||||
$ make setup
|
||||
$ make run
|
||||
|
||||
$ make clean
|
||||
|
||||
The eggs are built into an eggs subdirectory, because chicken-setup has
|
||||
problems installing eggs when there are other files named similar in
|
||||
the same directory. The make setup step runs chicken-setup to install
|
||||
the eggs into the eggs/install directory.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
%module mod1
|
||||
|
||||
%inline %{
|
||||
class Bar {
|
||||
public:
|
||||
int b;
|
||||
};
|
||||
%}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
%module mod2
|
||||
|
||||
%import "mod1.i"
|
||||
|
||||
%{
|
||||
class Bar {
|
||||
public:
|
||||
int b;
|
||||
};
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
class Bar2 : public Bar {
|
||||
public:
|
||||
int c;
|
||||
};
|
||||
%}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(run (csc -s -o multi.so multi_init.scm mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx))
|
||||
(install-extension 'multi '("multi.so"))
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(declare (uses mod1))
|
||||
(declare (uses mod2))
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
%module single
|
||||
|
||||
%inline %{
|
||||
class Foo {
|
||||
public:
|
||||
int a;
|
||||
};
|
||||
%}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(run (csc -s -o single.so single.scm single_wrap.cxx))
|
||||
(install-extension 'single '("single.so"))
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
(require-extension single)
|
||||
(require-extension multi)
|
||||
|
||||
(define f (make <Foo>))
|
||||
(slot-set! f 'a 3)
|
||||
(print (slot-ref f 'a))
|
||||
|
||||
(define b (make <Bar>))
|
||||
(slot-set! b 'b 2)
|
||||
(print (slot-ref b 'b))
|
||||
|
||||
(define b2 (make <Bar2>))
|
||||
(slot-set! b2 'b 4)
|
||||
(slot-set! b2 'c 6)
|
||||
(print (slot-ref b2 'b))
|
||||
(print (slot-ref b2 'c))
|
||||
|
||||
(exit 0)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
INTERFACE = example.i
|
||||
SRCS = example.c
|
||||
CXXSRCS =
|
||||
TARGET = multimap
|
||||
INCLUDE =
|
||||
SWIGOPT =
|
||||
VARIANT =
|
||||
|
||||
# uncomment the following two lines to build a static exe
|
||||
#CHICKEN_MAIN = runme.scm
|
||||
#VARIANT = _static
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
|
||||
|
||||
build: $(TARGET)
|
||||
|
||||
$(TARGET): $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
|
||||
rm -f example.scm
|
||||
rm -f $(TARGET)
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* File : example.c */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Compute the greatest common divisor of positive integers */
|
||||
int gcd(int x, int y) {
|
||||
int g;
|
||||
g = y;
|
||||
while (x > 0) {
|
||||
g = x;
|
||||
x = y % x;
|
||||
y = g;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
int gcdmain(int argc, char *argv[]) {
|
||||
int x,y;
|
||||
if (argc != 3) {
|
||||
printf("usage: gcd x y\n");
|
||||
return -1;
|
||||
}
|
||||
x = atoi(argv[1]);
|
||||
y = atoi(argv[2]);
|
||||
printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count(char *bytes, int len, char c) {
|
||||
int i;
|
||||
int count = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (bytes[i] == c) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void capitalize(char *str, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
str[i] = (char)toupper(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void circle(double x, double y) {
|
||||
double a = x*x + y*y;
|
||||
if (a > 1.0) {
|
||||
printf("Bad points %g, %g\n", x,y);
|
||||
} else {
|
||||
printf("Good points %g, %g\n", x,y);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
extern int gcd(int x, int y);
|
||||
extern int gcdmain(int argc, char *argv[]);
|
||||
extern int count(char *bytes, int len, char c);
|
||||
extern void capitalize (char *str, int len);
|
||||
extern void circle (double cx, double cy);
|
||||
extern int squareCubed (int n, int *OUTPUT);
|
||||
%}
|
||||
|
||||
%include exception.i
|
||||
%include typemaps.i
|
||||
|
||||
extern int gcd(int x, int y);
|
||||
|
||||
%typemap(in) (int argc, char *argv[]) {
|
||||
int i;
|
||||
if (!C_swig_is_vector ($input)) {
|
||||
swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a vector");
|
||||
}
|
||||
$1 = C_header_size ($input);
|
||||
$2 = (char **) malloc(($1+1)*sizeof(char *));
|
||||
for (i = 0; i < $1; i++) {
|
||||
C_word o = C_block_item ($input, i);
|
||||
if (!C_swig_is_string (o)) {
|
||||
char err[50];
|
||||
free($2);
|
||||
sprintf (err, "$input[%d] is not a string", i);
|
||||
swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, err);
|
||||
}
|
||||
$2[i] = C_c_string (o);
|
||||
}
|
||||
$2[i] = 0;
|
||||
}
|
||||
|
||||
%typemap(freearg) (int argc, char *argv[]) {
|
||||
free($2);
|
||||
}
|
||||
extern int gcdmain(int argc, char *argv[]);
|
||||
|
||||
%typemap(in) (char *bytes, int len) {
|
||||
if (!C_swig_is_string ($input)) {
|
||||
swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a string");
|
||||
}
|
||||
$1 = C_c_string ($input);
|
||||
$2 = C_header_size ($input);
|
||||
}
|
||||
|
||||
extern int count(char *bytes, int len, char c);
|
||||
|
||||
|
||||
/* This example shows how to wrap a function that mutates a string */
|
||||
|
||||
%typemap(in) (char *str, int len)
|
||||
%{ if (!C_swig_is_string ($input)) {
|
||||
swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a string");
|
||||
}
|
||||
$2 = C_header_size ($input);
|
||||
$1 = (char *) malloc ($2+1);
|
||||
memmove ($1, C_c_string ($input), $2);
|
||||
%}
|
||||
|
||||
/* Return the mutated string as a new object. Notice the if MANY construct ... they must be at column 0. */
|
||||
|
||||
%typemap(argout) (char *str, int len) (C_word *scmstr)
|
||||
%{ scmstr = C_alloc (C_SIZEOF_STRING ($2));
|
||||
SWIG_APPEND_VALUE(C_string (&scmstr, $2, $1));
|
||||
free ($1);
|
||||
%}
|
||||
|
||||
extern void capitalize (char *str, int len);
|
||||
|
||||
/* A multi-valued constraint. Force two arguments to lie
|
||||
inside the unit circle */
|
||||
|
||||
%typemap(check) (double cx, double cy) {
|
||||
double a = $1*$1 + $2*$2;
|
||||
if (a > 1.0) {
|
||||
SWIG_exception (SWIG_ValueError, "cx and cy must be in unit circle");
|
||||
}
|
||||
}
|
||||
|
||||
extern void circle (double cx, double cy);
|
||||
|
||||
/* Test out multiple return values */
|
||||
|
||||
extern int squareCubed (int n, int *OUTPUT);
|
||||
%{
|
||||
/* Returns n^3 and set n2 to n^2 */
|
||||
int squareCubed (int n, int *n2) {
|
||||
*n2 = n * n;
|
||||
return (*n2) * n;
|
||||
};
|
||||
%}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
;; feel free to uncomment and comment sections
|
||||
|
||||
(load-library 'example "multimap.so")
|
||||
|
||||
(display "(gcd 90 12): ")
|
||||
(display (gcd 90 12))
|
||||
(display "\n")
|
||||
|
||||
(display "(circle 0.5 0.5): ")
|
||||
(display (circle 0.5 0.5))
|
||||
(display "\n")
|
||||
|
||||
(display "(circle 1.0 1.0): ")
|
||||
(handle-exceptions exvar
|
||||
(if (= (car exvar) 9)
|
||||
(display "success: exception thrown")
|
||||
(display "an incorrect exception was thrown"))
|
||||
(begin
|
||||
(circle 1.0 1.0)
|
||||
(display "an exception was not thrown when it should have been")))
|
||||
(display "\n")
|
||||
|
||||
(display "(circle 1 1): ")
|
||||
(handle-exceptions exvar
|
||||
(if (= (car exvar) 9)
|
||||
(display "success: exception thrown")
|
||||
(display "an incorrect exception was thrown"))
|
||||
(begin
|
||||
(circle 1 1)
|
||||
(display "an exception was not thrown when it should have been")))
|
||||
(display "\n")
|
||||
|
||||
(display "(capitalize \"will this be all capital letters?\"): ")
|
||||
(display (capitalize "will this be all capital letters?"))
|
||||
(display "\n")
|
||||
|
||||
(display "(count \"jumpity little spider\" #\\t): ")
|
||||
(display (count "jumpity little spider" #\t))
|
||||
(display "\n")
|
||||
|
||||
(display "(gcdmain '#(\"hi\" \"there\")): ")
|
||||
(display (gcdmain '#("hi" "there")))
|
||||
(display "\n")
|
||||
|
||||
(display "(gcdmain '#(\"gcd\" \"9\" \"28\")): ")
|
||||
(gcdmain '#("gcd" "9" "28"))
|
||||
(display "\n")
|
||||
|
||||
(display "(gcdmain '#(\"gcd\" \"12\" \"90\")): ")
|
||||
(gcdmain '#("gcd" "12" "90"))
|
||||
(display "\n")
|
||||
|
||||
(display "squarecubed 3: ")
|
||||
(call-with-values (lambda() (squareCubed 3))
|
||||
(lambda (a b) (printf "~A ~A" a b)))
|
||||
(display "\n")
|
||||
|
||||
(exit)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
INTERFACE = example.i
|
||||
SRCS =
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = overload
|
||||
INCLUDE =
|
||||
SWIGOPT = -proxy -unhideprimitive
|
||||
VARIANT =
|
||||
|
||||
# uncomment the following lines to build a static exe
|
||||
#CHICKEN_MAIN = runme.scm
|
||||
#VARIANT = _static
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
|
||||
|
||||
build: $(TARGET)
|
||||
|
||||
$(TARGET): $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
|
||||
rm -f example.scm
|
||||
rm -f $(TARGET)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Overloading example from Chapter 5.14 of SWIG Core Documentation for
|
||||
version 1.3.
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/* File : example.c */
|
||||
|
||||
#include "example.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void foo(int x) {
|
||||
printf("x is %d\n", x);
|
||||
}
|
||||
|
||||
void foo(char *x) {
|
||||
printf("x is '%s'\n", x);
|
||||
}
|
||||
|
||||
Foo::Foo () {
|
||||
myvar = 55;
|
||||
printf ("Foo constructor called\n");
|
||||
}
|
||||
|
||||
Foo::Foo (const Foo &) {
|
||||
myvar = 66;
|
||||
printf ("Foo copy constructor called\n");
|
||||
}
|
||||
|
||||
void Foo::bar (int x) {
|
||||
printf ("Foo::bar(x) method ... \n");
|
||||
printf("x is %d\n", x);
|
||||
}
|
||||
|
||||
void Foo::bar (char *s, int y) {
|
||||
printf ("Foo::bar(s,y) method ... \n");
|
||||
printf ("s is '%s'\n", s);
|
||||
printf ("y is %d\n", y);
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
extern void foo (int x);
|
||||
extern void foo (char *x);
|
||||
|
||||
class Foo {
|
||||
private:
|
||||
int myvar;
|
||||
public:
|
||||
Foo();
|
||||
Foo(const Foo &); // Copy constructor
|
||||
void bar(int x);
|
||||
void bar(char *s, int y);
|
||||
};
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Let "Foo" objects be converted back and forth from TinyCLOS into
|
||||
low-level CHICKEN SWIG procedures */
|
||||
|
||||
%typemap(clos_in) Foo * = SIMPLE_CLOS_OBJECT *;
|
||||
%typemap(clos_out) Foo * = SIMPLE_CLOS_OBJECT *;
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
;; This file demonstrates the overloading capabilities of SWIG
|
||||
|
||||
(load-library 'example "overload.so")
|
||||
|
||||
;; Low level
|
||||
;; ---------
|
||||
|
||||
(display "
|
||||
Trying low level code ...
|
||||
(foo 1)
|
||||
(foo \"some string\")
|
||||
(define A-FOO (new-Foo))
|
||||
(define ANOTHER-FOO (new-Foo A-FOO)) ;; copy constructor
|
||||
(Foo-bar A-FOO 2)
|
||||
(Foo-bar ANOTHER-FOO \"another string\" 3)
|
||||
")
|
||||
|
||||
(primitive:foo 1)
|
||||
(primitive:foo "some string")
|
||||
(define A-FOO (slot-ref (primitive:new-Foo) 'swig-this))
|
||||
(define ANOTHER-FOO (slot-ref (primitive:new-Foo A-FOO) 'swig-this)) ;; copy constructor
|
||||
(primitive:Foo-bar A-FOO 2)
|
||||
(primitive:Foo-bar ANOTHER-FOO "another string" 3)
|
||||
|
||||
;; TinyCLOS
|
||||
;; --------
|
||||
|
||||
(display "
|
||||
Trying TinyCLOS code ...
|
||||
(+foo+ 1)
|
||||
(+foo+ \"some string\")
|
||||
(define A-FOO (make <Foo>))
|
||||
(define ANOTHER-FOO (make <Foo> A-FOO)) ;; copy constructor
|
||||
(-bar- A-FOO 2)
|
||||
(-bar- ANOTHER-FOO \"another string\" 3)
|
||||
")
|
||||
|
||||
(foo 1)
|
||||
(foo "some string")
|
||||
(define A-FOO (make <Foo>))
|
||||
(define ANOTHER-FOO (make <Foo> A-FOO)) ;; copy constructor
|
||||
(bar A-FOO 2)
|
||||
(bar ANOTHER-FOO "another string" 3)
|
||||
|
||||
(exit)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
INTERFACE = example.i
|
||||
SRCS = example.c
|
||||
CXXSRCS =
|
||||
TARGET = simple
|
||||
INCLUDE =
|
||||
SWIGOPT =
|
||||
VARIANT =
|
||||
|
||||
# uncomment the following two lines to build a static exe
|
||||
#CHICKEN_MAIN = runme.scm
|
||||
#VARIANT = _static
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
|
||||
|
||||
build: $(TARGET)
|
||||
|
||||
$(TARGET): $(INTERFACE) $(SRCS)
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
|
||||
SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
|
||||
INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
|
||||
rm -f example.scm example-generic.scm example-clos.scm
|
||||
rm -f $(TARGET)
|
||||
|
|
@ -1 +0,0 @@
|
|||
Simple example from users manual.
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* Simple example from documentation */
|
||||
/* File : example.c */
|
||||
|
||||
#include <time.h>
|
||||
|
||||
double My_variable = 3.0;
|
||||
|
||||
/* Compute factorial of n */
|
||||
int fact(int n) {
|
||||
if (n <= 1) return 1;
|
||||
else return n*fact(n-1);
|
||||
}
|
||||
|
||||
/* Compute n mod m */
|
||||
int my_mod(int n, int m) {
|
||||
return (n % m);
|
||||
}
|
||||
|
||||
|
||||
char *get_time() {
|
||||
long ltime;
|
||||
time(<ime);
|
||||
return ctime(<ime);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
%{
|
||||
/* Put headers and other declarations here */
|
||||
%}
|
||||
|
||||
%include typemaps.i
|
||||
|
||||
%rename(mod) my_mod;
|
||||
|
||||
%inline %{
|
||||
extern double My_variable;
|
||||
extern int fact(int);
|
||||
extern int my_mod(int n, int m);
|
||||
extern char *get_time();
|
||||
%}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
;; feel free to uncomment and comment sections
|
||||
(load-library 'example "simple.so")
|
||||
|
||||
(display "(My-variable): ")
|
||||
(display (My-variable))
|
||||
(display "\n")
|
||||
|
||||
(display "(My-variable 3.141259): ")
|
||||
(display (My-variable 3.141259))
|
||||
(display "\n")
|
||||
|
||||
(display "(My-variable): ")
|
||||
(display (My-variable))
|
||||
(display "\n")
|
||||
|
||||
(display "(fact 5): ")
|
||||
(display (fact 5))
|
||||
(display "\n")
|
||||
|
||||
(display "(mod 75 7): ")
|
||||
(display (mod 75 7))
|
||||
(display "\n")
|
||||
|
||||
(display "(get-time): ")
|
||||
(display (get-time))
|
||||
(display "\n")
|
||||
|
||||
(exit)
|
||||
|
|
@ -14,4 +14,8 @@
|
|||
|
||||
%include math.i
|
||||
|
||||
extern double drand48();
|
||||
%{
|
||||
/* Add drand48 declaration as it is posix only and is not in stdlib.h when using strict c99 and later */
|
||||
extern double drand48(void);
|
||||
%}
|
||||
extern double drand48(void);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Exc {
|
|||
public:
|
||||
Exc(int c, const char *m) {
|
||||
code = c;
|
||||
strncpy(msg,m,256);
|
||||
strncpy(msg,m,255);
|
||||
}
|
||||
int code;
|
||||
char msg[256];
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class Exc {
|
|||
public:
|
||||
Exc(int c, const char *m) {
|
||||
code = c;
|
||||
strncpy(msg,m,256);
|
||||
strncpy(msg,m,255);
|
||||
}
|
||||
int code;
|
||||
char msg[256];
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
# see top-level Makefile.in
|
||||
class
|
||||
enum
|
||||
exception
|
||||
reference
|
||||
simple
|
||||
typemap
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
SRCS =
|
||||
TARGET = example
|
||||
PLATFORM = LINUXLIBC6
|
||||
INTERFACE = example.i
|
||||
SWIGOPT = -c++
|
||||
MODULA3SRCS = *.[im]3
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
# compilation of example_wrap.cxx is started by cm3
|
||||
# $(CXX) -c $(TARGET)_wrap.cxx
|
||||
mv example_wrap.cxx m3makefile $(MODULA3SRCS) src/
|
||||
ln -sf ../example.h src/example.h
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
/* Move the shape to a new location */
|
||||
void Shape::move(double dx, double dy) {
|
||||
x += dx;
|
||||
y += dy;
|
||||
}
|
||||
|
||||
int Shape::nshapes = 0;
|
||||
|
||||
double Circle::area() {
|
||||
return M_PI*radius*radius;
|
||||
}
|
||||
|
||||
double Circle::perimeter() {
|
||||
return 2*M_PI*radius;
|
||||
}
|
||||
|
||||
double Square::area() {
|
||||
return width*width;
|
||||
}
|
||||
|
||||
double Square::perimeter() {
|
||||
return 4*width;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
class Shape {
|
||||
public:
|
||||
Shape() {
|
||||
nshapes++;
|
||||
}
|
||||
virtual ~Shape() {
|
||||
nshapes--;
|
||||
}
|
||||
double x, y;
|
||||
void move(double dx, double dy);
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
static int nshapes;
|
||||
};
|
||||
|
||||
class Circle : public Shape {
|
||||
private:
|
||||
double radius;
|
||||
public:
|
||||
Circle(double r) : radius(r) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
|
||||
class Square : public Shape {
|
||||
private:
|
||||
double width;
|
||||
public:
|
||||
Square(double w) : width(w) { }
|
||||
virtual double area();
|
||||
virtual double perimeter();
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module Example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%insert(m3makefile) %{template("../swig")
|
||||
cxx_source("example_wrap")%}
|
||||
|
||||
%typemap(m3rawinmode) Shape *, Circle *, Square * ""
|
||||
%typemap(m3rawrettype) Shape *, Circle *, Square * "$1_basetype"
|
||||
|
||||
%typemap(m3wrapinmode) Shape *, Circle *, Square * ""
|
||||
%typemap(m3wrapargraw) Shape *, Circle *, Square * "self.cxxObj"
|
||||
|
||||
%typemap(m3wrapretvar) Circle *, Square * "cxxObj : ExampleRaw.$1_basetype;"
|
||||
%typemap(m3wrapretraw) Circle *, Square * "cxxObj"
|
||||
%typemap(m3wrapretconv) Circle *, Square * "NEW($1_basetype,cxxObj:=cxxObj)"
|
||||
%typemap(m3wraprettype) Circle *, Square * "$1_basetype"
|
||||
|
||||
/* Should work with and without renaming
|
||||
%rename(M3Shape) Shape;
|
||||
%rename(M3Circle) Circle;
|
||||
%rename(M3Square) Square;
|
||||
%typemap(m3wrapintype) Shape *, Circle *, Square * "M3$1_basetype"
|
||||
%typemap(m3wraprettype) Shape *, Circle *, Square * "M3$1_basetype"
|
||||
%typemap(m3wrapretconv) Circle *, Square * "NEW(M3$1_basetype,cxxObj:=cxxObj)"
|
||||
*/
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
readonly proc cxx_source (X) is
|
||||
local cxxfile = X&".cxx"
|
||||
local objfile = X&".o"
|
||||
%exec("echo $PWD")
|
||||
if stale(objfile,cxxfile)
|
||||
exec("cd",path(),"; g++ -I.. -c -o",objfile,cxxfile)
|
||||
end
|
||||
import_obj(X)
|
||||
%unlink_file(path()&SL&objfile)
|
||||
end
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
SRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
CONSTNUMERIC = example_const
|
||||
SWIGOPT = -c++
|
||||
MODULA3SRCS = *.[im]3
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(SWIGEXE) -modula3 $(SWIGOPT) -module Example -generateconst $(CONSTNUMERIC) $(TARGET).h
|
||||
$(CXX) -Wall $(CONSTNUMERIC).c -o $(CONSTNUMERIC)
|
||||
$(CONSTNUMERIC) >$(CONSTNUMERIC).i
|
||||
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
mv m3makefile $(MODULA3SRCS) src/
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void Foo::enum_test(speed s) {
|
||||
if (s == IMPULSE) {
|
||||
printf("IMPULSE speed\n");
|
||||
} else if (s == WARP) {
|
||||
printf("WARP speed\n");
|
||||
} else if (s == LUDICROUS) {
|
||||
printf("LUDICROUS speed\n");
|
||||
} else if (s == HYPER) {
|
||||
printf("HYPER speed\n");
|
||||
} else {
|
||||
printf("Unknown speed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void enum_test(color c, Foo::speed s) {
|
||||
if (c == RED) {
|
||||
printf("color = RED, ");
|
||||
} else if (c == BLUE) {
|
||||
printf("color = BLUE, ");
|
||||
} else if (c == GREEN) {
|
||||
printf("color = GREEN, ");
|
||||
} else {
|
||||
printf("color = Unknown color!, ");
|
||||
}
|
||||
Foo obj;
|
||||
obj.enum_test(s);
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
#define PI 3.141
|
||||
|
||||
#define DAY_MONDAY 0
|
||||
#define DAY_TUESDAY 1
|
||||
#define DAY_WEDNESDAY 2
|
||||
#define DAY_THURSDAY 3
|
||||
#define DAY_FRIDAY 4
|
||||
#define DAY_SATURDAY 5
|
||||
#define DAY_SUNDAY 6
|
||||
|
||||
enum color { BLUE, RED, GREEN };
|
||||
|
||||
#define CLB_BLACK 0
|
||||
#define CLB_BLUE 1
|
||||
#define CLB_RED 2
|
||||
#define CLB_MAGENTA 3
|
||||
#define CLB_GREEN 4
|
||||
#define CLB_CYAN 5
|
||||
#define CLB_YELLOW 6
|
||||
#define CLB_WHITE 7
|
||||
|
||||
/* Using this would be good style
|
||||
which cannot be expected for general C header files.
|
||||
Instead I want to demonstrate how to live without it.
|
||||
enum month {
|
||||
MTHF_JANUARY,
|
||||
MTHF_FEBRUARY,
|
||||
MTHF_MARCH,
|
||||
MTHF_APRIL,
|
||||
MTHF_MAY,
|
||||
MTHF_JUNE,
|
||||
MTHF_JULY,
|
||||
MTHF_AUGUST,
|
||||
MTHF_SEPTEMBER,
|
||||
MTHF_OCTOBER,
|
||||
MTHF_NOVEMBER,
|
||||
MTHF_DECEMBER,
|
||||
}
|
||||
*/
|
||||
|
||||
/* Since there are no compile time constants in C / C++
|
||||
it is a common abuse
|
||||
to declare bit set (flag) constants
|
||||
as enumerations. */
|
||||
enum calendar {
|
||||
MTHB_JANUARY = 1 << 0, /* 1 << MTHF_JANUARY, */
|
||||
MTHB_FEBRUARY = 1 << 1, /* 1 << MTHF_FEBRUARY, */
|
||||
MTHB_MARCH = 1 << 2, /* 1 << MTHF_MARCH, */
|
||||
MTHB_APRIL = 1 << 3, /* 1 << MTHF_APRIL, */
|
||||
MTHB_MAY = 1 << 4, /* 1 << MTHF_MAY, */
|
||||
MTHB_JUNE = 1 << 5, /* 1 << MTHF_JUNE, */
|
||||
MTHB_JULY = 1 << 6, /* 1 << MTHF_JULY, */
|
||||
MTHB_AUGUST = 1 << 7, /* 1 << MTHF_AUGUST, */
|
||||
MTHB_SEPTEMBER = 1 << 8, /* 1 << MTHF_SEPTEMBER, */
|
||||
MTHB_OCTOBER = 1 << 9, /* 1 << MTHF_OCTOBER, */
|
||||
MTHB_NOVEMBER = 1 << 10, /* 1 << MTHF_NOVEMBER, */
|
||||
MTHB_DECEMBER = 1 << 11, /* 1 << MTHF_DECEMBER, */
|
||||
|
||||
MTHB_SPRING = MTHB_MARCH | MTHB_APRIL | MTHB_MAY,
|
||||
MTHB_SUMMER = MTHB_JUNE | MTHB_JULY | MTHB_AUGUST,
|
||||
MTHB_AUTUMN = MTHB_SEPTEMBER | MTHB_OCTOBER | MTHB_NOVEMBER,
|
||||
MTHB_WINTER = MTHB_DECEMBER | MTHB_JANUARY | MTHB_FEBRUARY,
|
||||
};
|
||||
|
||||
|
||||
namespace Answer {
|
||||
enum {
|
||||
UNIVERSE_AND_EVERYTHING = 42,
|
||||
SEVENTEEN_AND_FOUR = 21,
|
||||
TWOHUNDRED_PERCENT_OF_NOTHING = 0,
|
||||
};
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Foo() { }
|
||||
enum speed { IMPULSE = -2, WARP = 0, HYPER, LUDICROUS = 3};
|
||||
void enum_test(speed s);
|
||||
};
|
||||
};
|
||||
|
||||
void enum_test(color c, Answer::Foo::speed s);
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module Example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example_const.i"
|
||||
|
||||
// such features are generated by the following pragmas
|
||||
#if 0
|
||||
%feature("modula3:enumitem:enum","Days") DAY_MONDAY;
|
||||
%feature("modula3:enumitem:name","monday") DAY_MONDAY;
|
||||
%feature("modula3:enumitem:conv","int:int") DAY_MONDAY;
|
||||
|
||||
%feature("modula3:enumitem:enum","Month") MTHB_JANUARY;
|
||||
%feature("modula3:enumitem:name","january") MTHB_JANUARY;
|
||||
%feature("modula3:enumitem:conv","set:int") MTHB_JANUARY;
|
||||
//%feature("modula3:constset:type","MonthSet") MTHB_JANUARY; /*type in the constant definition*/
|
||||
%feature("modula3:constset:set", "MonthSet") MTHB_JANUARY; /*remarks that the 'type' is a set type*/
|
||||
%feature("modula3:constset:base","Month") MTHB_JANUARY;
|
||||
%feature("modula3:constset:name","monthsJanuary") MTHB_JANUARY;
|
||||
%feature("modula3:constset:conv","set:set") MTHB_JANUARY; /*conversion of the bit pattern: no change*/
|
||||
|
||||
%feature("modula3:enumitem:enum","Color") BLUE;
|
||||
%feature("modula3:enumitem:name","blue") BLUE;
|
||||
%feature("modula3:enumitem:conv","int:int") BLUE;
|
||||
|
||||
%feature("modula3:constint:type","INTEGER") Foo::IMPULSE;
|
||||
%feature("modula3:constint:name","impulse") Foo::IMPULSE;
|
||||
%feature("modula3:constint:conv","int:int") Foo::IMPULSE;
|
||||
#endif
|
||||
|
||||
%rename(pi) PI;
|
||||
|
||||
%pragma(modula3) enumitem="prefix=DAY_;int;srcstyle=underscore;Day";
|
||||
|
||||
%pragma(modula3) enumitem="enum=color;int;srcstyle=underscore;Color";
|
||||
%pragma(modula3) makesetofenum="Color";
|
||||
%pragma(modula3) constset="prefix=CLB_;set;srcstyle=underscore,prefix=clb;ColorSet,Color";
|
||||
|
||||
%pragma(modula3) enumitem="prefix=MTHB_,enum=calendar;set;srcstyle=underscore;Month";
|
||||
%pragma(modula3) makesetofenum="Month";
|
||||
%pragma(modula3) constset="prefix=MTHB_,enum=calendar;set;srcstyle=underscore,prefix=monthset;MonthSet,Month";
|
||||
|
||||
%pragma(modula3) constint="prefix=Answer::Foo::,enum=Answer::Foo::speed;int;srcstyle=underscore,prefix=speed;INTEGER";
|
||||
|
||||
%pragma(modula3) constint="prefix=Answer::,enum=Answer::;int;srcstyle=underscore,prefix=answer;CARDINAL";
|
||||
|
||||
%rename(AnswerFoo) Answer::Foo;
|
||||
%typemap("m3rawrettype") Answer::Foo * %{AnswerFoo%}
|
||||
%typemap("m3rawintype") Answer::Foo * %{AnswerFoo%}
|
||||
%typemap("m3rawinmode") Answer::Foo * %{%}
|
||||
%typemap("m3wraprettype") Answer::Foo * %{AnswerFoo%}
|
||||
%typemap("m3wrapintype") Answer::Foo * %{AnswerFoo%}
|
||||
%typemap("m3wrapinmode") Answer::Foo * %{%}
|
||||
%typemap("m3wrapargraw") Answer::Foo * %{self.cxxObj%}
|
||||
|
||||
%typemap("m3wrapretvar") Answer::Foo * %{cxxObj : ExampleRaw.AnswerFoo;%}
|
||||
%typemap("m3wrapretraw") Answer::Foo * %{cxxObj%}
|
||||
%typemap("m3wrapretconv") Answer::Foo * %{NEW(AnswerFoo,cxxObj:=cxxObj)%}
|
||||
|
||||
|
||||
%typemap("m3rawintype") Answer::Foo::speed %{C.int%};
|
||||
%typemap("m3rawintype:import") Answer::Foo::speed %{Ctypes AS C%};
|
||||
%typemap("m3wrapintype") Answer::Foo::speed %{[-2..3]%};
|
||||
|
||||
%typemap("m3wrapintype") color %{Color%};
|
||||
%typemap("m3wrapargraw") color %{ORD($1_name)%};
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
MODULA3SRCS = *.[im]3
|
||||
MODULA3FLAGS= -o runme
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3_cpp
|
||||
# $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' MODULA3SRCS='$(MODULA3SRCS)' MODULA3FLAGS='$(MODULA3FLAGS)' modula3_compile
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
mv m3makefile $(MODULA3SRCS) src/
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
enum error {OK, OVERFLOW, DIVISION_BY_ZERO, NEGATIVE_RADICAND, NEGATIVE_BASE};
|
||||
typedef error errorstate; /* just to separate the typemaps */
|
||||
|
||||
error acc_add (double &x, double y);
|
||||
error acc_sub (double &x, double y);
|
||||
error acc_mul (double &x, double y);
|
||||
error acc_div (double &x, double y);
|
||||
|
||||
double op_add (double x, double y, errorstate &err);
|
||||
double op_sub (double x, double y, errorstate &err);
|
||||
double op_mul (double x, double y, errorstate &err);
|
||||
double op_div (double x, double y, errorstate &err);
|
||||
double op_sqrt (double x, errorstate &err);
|
||||
double op_pow (double x, double y, errorstate &err);
|
||||
|
||||
double op_noexc (double x, double y);
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module Example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%insert(m3wrapintf) %{
|
||||
EXCEPTION E(Error);
|
||||
%}
|
||||
%insert(m3wrapimpl) %{
|
||||
IMPORT Ctypes AS C;
|
||||
%}
|
||||
|
||||
%pragma(modula3) enumitem="enum=error;int;srcstyle=underscore;Error";
|
||||
|
||||
%typemap("m3rawintype") double & %{C.double%};
|
||||
%typemap("m3wrapintype") double & %{LONGREAL%};
|
||||
|
||||
%typemap("m3wraprettype") error ""
|
||||
%typemap("m3wrapretvar") error "rawerr: C.int;"
|
||||
%typemap("m3wrapretraw") error "rawerr"
|
||||
%typemap("m3wrapretcheck:throws") error "E"
|
||||
%typemap("m3wrapretcheck") error
|
||||
%{VAR err := VAL(rawerr, Error);
|
||||
BEGIN
|
||||
IF err # Error.ok THEN
|
||||
RAISE E(err);
|
||||
END;
|
||||
END;%}
|
||||
|
||||
%typemap("m3rawintype") errorstate & %{C.int%};
|
||||
%typemap("m3wrapintype",numinputs=0) errorstate & %{%};
|
||||
%typemap("m3wrapargvar") errorstate & %{err:C.int:=ORD(Error.ok);%};
|
||||
%typemap("m3wrapoutcheck:throws") errorstate & "E";
|
||||
%typemap("m3wrapoutcheck") errorstate &
|
||||
%{IF VAL(err,Error) # Error.ok THEN
|
||||
RAISE E(VAL(err,Error));
|
||||
END;%}
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
SRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT = -c++
|
||||
MODULA3SRCS = *.[im]3
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
mv m3makefile $(MODULA3SRCS) src/
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
|
||||
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
|
||||
# define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#include "example.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Vector operator+(const Vector &a, const Vector &b) {
|
||||
Vector r;
|
||||
r.x = a.x + b.x;
|
||||
r.y = a.y + b.y;
|
||||
r.z = a.z + b.z;
|
||||
return r;
|
||||
}
|
||||
|
||||
char *Vector::print() {
|
||||
static char temp[512];
|
||||
sprintf(temp,"Vector %p (%g,%g,%g)", (void *)this, x,y,z);
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorArray::VectorArray(int size) {
|
||||
items = new Vector[size];
|
||||
maxsize = size;
|
||||
}
|
||||
|
||||
VectorArray::~VectorArray() {
|
||||
delete [] items;
|
||||
}
|
||||
|
||||
Vector &VectorArray::operator[](int index) {
|
||||
if ((index < 0) || (index >= maxsize)) {
|
||||
printf("Panic! Array index out of bounds.\n");
|
||||
exit(1);
|
||||
}
|
||||
return items[index];
|
||||
}
|
||||
|
||||
int VectorArray::size() {
|
||||
return maxsize;
|
||||
}
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* File : example.h */
|
||||
|
||||
struct Vector {
|
||||
private:
|
||||
double x,y,z;
|
||||
public:
|
||||
Vector() : x(0), y(0), z(0) { }
|
||||
Vector(double x, double y, double z) : x(x), y(y), z(z) { }
|
||||
Vector operator+(const Vector &b) const;
|
||||
char *print();
|
||||
};
|
||||
|
||||
struct VectorArray {
|
||||
private:
|
||||
Vector *items;
|
||||
int maxsize;
|
||||
public:
|
||||
VectorArray(int maxsize);
|
||||
~VectorArray();
|
||||
Vector &operator[](int);
|
||||
int size();
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* File : example.i */
|
||||
|
||||
/* This file has a few "typical" uses of C++ references. */
|
||||
|
||||
%module Example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%pragma(modula3) unsafe="1";
|
||||
|
||||
%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Vector, VectorArray;%}
|
||||
%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Vector, VectorArray;%}
|
||||
|
||||
%typemap(m3wrapretvar) Vector %{vec: UNTRACED REF Vector;%}
|
||||
%typemap(m3wrapretraw) Vector %{vec%}
|
||||
%typemap(m3wrapretconv) Vector %{vec^%}
|
||||
|
||||
|
||||
/* This helper function calls an overloaded operator */
|
||||
%inline %{
|
||||
Vector addv(const Vector &a, const Vector &b) {
|
||||
return a+b;
|
||||
}
|
||||
%}
|
||||
|
||||
%rename(Vector_Clear) Vector::Vector();
|
||||
%rename(Add) Vector::operator+;
|
||||
%rename(GetItem) VectorArray::operator[];
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
SRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
MODULA3SRCS = *.[im]3
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
mv m3makefile $(MODULA3SRCS) src/
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/* File : example.c */
|
||||
|
||||
/* A global variable */
|
||||
double Foo = 3.0;
|
||||
|
||||
/* Compute the greatest common divisor of positive integers */
|
||||
int gcd(int x, int y) {
|
||||
int g;
|
||||
g = y;
|
||||
while (x > 0) {
|
||||
g = x;
|
||||
x = y % x;
|
||||
y = g;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module Example
|
||||
|
||||
%inline %{
|
||||
extern int gcd(int x, int y);
|
||||
extern double Foo;
|
||||
%}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
TOP = ../..
|
||||
SWIGEXE = $(TOP)/../swig
|
||||
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
|
||||
SRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
SWIGOPT =
|
||||
MODULA3SRCS = *.[im]3
|
||||
|
||||
check: build
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
|
||||
|
||||
build:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
|
||||
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
|
||||
m3ppinplace $(MODULA3SRCS)
|
||||
mv m3makefile $(MODULA3SRCS) src/
|
||||
cm3
|
||||
|
||||
clean:
|
||||
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/* File : example.i */
|
||||
%module Example
|
||||
|
||||
%pragma(modula3) unsafe="true";
|
||||
|
||||
%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Window, Point;
|
||||
%}
|
||||
%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Window, Point;
|
||||
IMPORT M3toC;
|
||||
IMPORT Ctypes AS C;
|
||||
%}
|
||||
|
||||
/* Typemap applied to patterns of multiple arguments */
|
||||
|
||||
%typemap(m3rawinmode) (char *outstr) %{VAR%}
|
||||
%typemap(m3rawintype) (char *outstr) %{CHAR%}
|
||||
%typemap(m3wrapinmode) (char *outstr, int size) %{VAR%}
|
||||
%typemap(m3wrapintype) (char *outstr, int size) %{ARRAY OF CHAR%}
|
||||
%typemap(m3wrapargraw) (char *outstr, int size) %{$1_name[0], NUMBER($1_name)%}
|
||||
|
||||
|
||||
%typemap(m3rawinmode) (const struct Window *) %{READONLY%}
|
||||
%typemap(m3wrapinmode) (const struct Window *) %{READONLY%}
|
||||
%typemap(m3rawintype) ( struct Window *) %{Window%}
|
||||
%typemap(m3wrapintype) ( struct Window *) %{Window%}
|
||||
|
||||
%typemap(m3rawinmode) (const char *str []) %{READONLY%}
|
||||
%typemap(m3wrapinmode) (const char *str []) %{READONLY%}
|
||||
%typemap(m3rawintype) (const char *str []) %{(*ARRAY OF*) C.char_star%}
|
||||
%typemap(m3wrapintype) (const char *str []) %{ARRAY OF TEXT%}
|
||||
%typemap(m3wrapargvar) (const char *str []) %{$1: REF ARRAY OF C.char_star;%}
|
||||
%typemap(m3wrapargraw) (const char *str []) %{$1[0]%}
|
||||
%typemap(m3wrapinconv) (const char *str []) %{$1:= NEW(REF ARRAY OF C.char_star,NUMBER($1_name));
|
||||
FOR i:=FIRST($1_name) TO LAST($1_name) DO
|
||||
$1[i]:=M3toC.SharedTtoS($1_name[i]);
|
||||
END;%}
|
||||
%typemap(m3wrapfreearg) (const char *str [])
|
||||
%{FOR i:=FIRST($1_name) TO LAST($1_name) DO
|
||||
M3toC.FreeSharedS($1_name[i],$1[i]);
|
||||
END;%}
|
||||
|
||||
%typemap(m3wraprettype) char * %{TEXT%}
|
||||
%typemap(m3wrapretvar) char * %{result_string: C.char_star;%}
|
||||
%typemap(m3wrapretraw) char * %{result_string%}
|
||||
%typemap(m3wrapretconv) char * %{M3toC.CopyStoT(result_string)%}
|
||||
|
||||
struct Window {
|
||||
char *label;
|
||||
int left,top,width,height;
|
||||
};
|
||||
|
||||
|
||||
%typemap(m3wrapinname) (int x, int y) %{p%}
|
||||
%typemap(m3wrapinmode) (int x, int y) %{READONLY%}
|
||||
%typemap(m3wrapintype) (int x, int y) %{Point%}
|
||||
%typemap(m3wrapargraw) (int x, int y) %{p.$1_name, p.$2_name%}
|
||||
|
||||
%typemap(m3wrapargraw) (int &x, int &y) %{p.$1_name, p.$2_name%}
|
||||
%typemap(m3wrapintype) (int &x, int &y) %{Point%}
|
||||
%typemap(m3wrapoutname) (int &x, int &y) %{p%}
|
||||
%typemap(m3wrapouttype) (int &x, int &y) %{Point%}
|
||||
%typemap(m3wrapargdir) (int &x, int &y) "out"
|
||||
|
||||
|
||||
%typemap(m3wrapargvar) int &left, int &top, int &width, int &height "$1:C.int;"
|
||||
%typemap(m3wrapargraw) int &left, int &top, int &width, int &height "$1"
|
||||
%typemap(m3wrapoutconv) int &left, int &top, int &width, int &height "$1"
|
||||
|
||||
%typemap(m3wrapargdir) int &left, int &top "out"
|
||||
|
||||
%typemap(m3wrapouttype) int &width, int &height "CARDINAL"
|
||||
%typemap(m3wrapargdir) int &width, int &height "out"
|
||||
|
||||
struct Point {
|
||||
int x,y;
|
||||
};
|
||||
|
||||
%m3multiretval get_box;
|
||||
|
||||
void set_label ( struct Window *win, const char *str, bool activate);
|
||||
void set_multi_label ( struct Window *win, const char *str []);
|
||||
void write_label (const struct Window *win, char *outstr, int size);
|
||||
int get_label (const struct Window *win, char *outstr, int size);
|
||||
char *get_label_ptr (const struct Window *win);
|
||||
void move(struct Window *win, int x, int y);
|
||||
int get_area(const struct Window *win);
|
||||
void get_box(const struct Window *win, int &left, int &top, int &width, int &height);
|
||||
void get_left(const struct Window *win, int &left);
|
||||
void get_mouse(const struct Window *win, int &x, int &y);
|
||||
int get_attached_data(const struct Window *win, const char *id);
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
#ifndef SWIGSEXP
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
#endif
|
||||
|
||||
%feature("director");
|
||||
%include "example.h"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# Class, which overwrites Callback::run().
|
||||
|
||||
class PhpCallback extends Callback {
|
||||
|
|
@ -43,5 +41,3 @@ $caller->delCallback();
|
|||
# All done.
|
||||
|
||||
print "php exit\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
# This example illustrates how member variables are wrapped.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# ----- Object creation -----
|
||||
|
||||
print "Creating some objects:\n";
|
||||
|
|
@ -56,5 +54,3 @@ $o = NULL;
|
|||
|
||||
print Shape::nshapes() . " shapes remain\n";
|
||||
print "Goodbye\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require "example.php";
|
||||
|
||||
print "ICONST = " . ICONST . " (should be 42)\n";
|
||||
print "FCONST = " . FCONST . " (should be 2.1828)\n";
|
||||
print "CCONST = " . CCONST . " (should be 'x')\n";
|
||||
|
|
@ -19,6 +17,3 @@ if (array_key_exists("EXTERN", $c)) {
|
|||
if (array_key_exists("FOO", $c)) {
|
||||
print "FOO = " . $c["FOO"] . " (Arg! This shouldn't print anything)\n";
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require "example.php";
|
||||
|
||||
# First create some objects using the pointer library.
|
||||
|
||||
print "Testing the pointer library\n";
|
||||
|
|
@ -43,5 +41,3 @@
|
|||
# $q = $a[0]
|
||||
# $r = $a[1]
|
||||
# print " 42/37 = $q remainder $r\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
# created by SWIG. In this case, all of our C++ classes
|
||||
# get converted into function calls.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# ----- Object creation -----
|
||||
|
||||
print "Creating some objects:\n";
|
||||
|
|
@ -45,5 +43,3 @@ $container = NULL;
|
|||
print "\nA total of " . Shape::nshapes() . " shapes remain\n";
|
||||
|
||||
print "Goodbye\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require "example.php";
|
||||
|
||||
# ----- Object creation -----
|
||||
|
||||
# Print out the value of some enums
|
||||
|
|
@ -28,5 +26,3 @@ $f = new Foo();
|
|||
$f->enum_test(Foo::IMPULSE);
|
||||
$f->enum_test(Foo::WARP);
|
||||
$f->enum_test(Foo::LUDICROUS);
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# CEO class, which overrides Employee::getPosition().
|
||||
|
||||
class CEO extends Manager {
|
||||
|
|
@ -72,5 +70,3 @@ print "----------------------\n";
|
|||
# All done.
|
||||
|
||||
print "php exit\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
require "example.php";
|
||||
|
||||
$a = 37;
|
||||
$b = 42;
|
||||
|
||||
|
|
@ -10,15 +8,11 @@ $b = 42;
|
|||
print "Trying some C callback functions\n";
|
||||
print " a = $a\n";
|
||||
print " b = $b\n";
|
||||
print " ADD(a,b) = ". do_op($a,$b,ADD)."\n";
|
||||
print " SUB(a,b) = ". do_op($a,$b,SUB)."\n";
|
||||
print " MUL(a,b) = ". do_op($a,$b,MUL)."\n";
|
||||
print " ADD(a,b) = ". do_op($a,$b,example::ADD)."\n";
|
||||
print " SUB(a,b) = ". do_op($a,$b,example::SUB)."\n";
|
||||
print " MUL(a,b) = ". do_op($a,$b,example::MUL)."\n";
|
||||
|
||||
print "Here is what the C callback function objects look like in php\n";
|
||||
print "Using swig style string pointers as we need them registered as constants\n";
|
||||
print " ADD = " . ADD . "\n";
|
||||
print " SUB = " . SUB . "\n";
|
||||
print " MUL = " . MUL . "\n";
|
||||
|
||||
?>
|
||||
|
||||
print " ADD = " . example::ADD . "\n";
|
||||
print " SUB = " . example::SUB . "\n";
|
||||
print " MUL = " . example::MUL . "\n";
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue