summaryrefslogtreecommitdiff
path: root/Doc
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2022-10-06 23:12:38 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2022-10-06 23:29:33 +0100
commitcea25abca535fa27b89eedaf2dd978991b42e1a5 (patch)
tree85e669698ad41a576e5ccdf52eef8de35340e92e /Doc
parent7b0f7caaf2c4d8e863b38a88099ea9dd7e3df0e5 (diff)
downloadswig-cea25abca535fa27b89eedaf2dd978991b42e1a5.tar.gz
Completely remove CFFI
No meaningful progress to update CFFI to experimental status has been made since CFFI was disabled in SWIG-4.0.0 as the first stage to removal. This commit is the final stage to remove it. See issue #1966 for an attempt at updating CFFI to experimental status. Anyone wishing for SWIG to support CFFI again might want to utilise this work.
Diffstat (limited to 'Doc')
-rw-r--r--Doc/Manual/Lisp.html604
1 files changed, 0 insertions, 604 deletions
diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html
deleted file mode 100644
index 6d8463beb..000000000
--- a/Doc/Manual/Lisp.html
+++ /dev/null
@@ -1,604 +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 Common Lisp</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="Lisp">29 SWIG and Common Lisp</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Lisp_nn3">Common Foreign Function Interface(CFFI)</a>
-<ul>
-<li><a href="#Lisp_nn4">Additional Commandline Options </a>
-<li><a href="#Lisp_nn5">Generating CFFI bindings</a>
-<li><a href="#Lisp_nn6">Generating CFFI bindings for C++ code</a>
-<li><a href="#Lisp_nn7">Inserting user code into generated files</a>
-</ul>
-<ul>
-<li><a href="#Lisp_nn9">Additional Commandline Options </a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
- Common Lisp is a high-level, all-purpose, object-oriented,
- dynamic, functional programming language with long history.
- Common Lisp is used in many fields, ranging from web development to
- finance, and also common in computer science education.
- There are more than 9 different implementations of common lisp which
- are available, all have different foreign function
- interfaces. SWIG currently supports the
- Common Foreign Function Interface(CFFI).
-</p>
-
-<H2><a name="Lisp_nn3">29.2 Common Foreign Function Interface(CFFI)</a></H2>
-
-
-<p>
- CFFI, the Common Foreign Function Interface, is a portable foreign
- function interface for ANSI Common Lisp systems.
- CFFI requires only a small set of
- low-level functionality from the Lisp implementation, such as
- calling a foreign function by name, allocating foreign memory,
- and dereferencing pointers.
-</p>
-
-<p>
- To run the cffi module of SWIG requires very little effort, you
- just need to run:
-</p>
-<div class="code"><pre>
-swig -cffi -module <i>module-name</i> <i>file-name</i>
-
-</pre></div>
-
-<p>
- But a better was of using all the power of SWIG is to write SWIG
- interface files. Below we will explain how to write interface
- files and the various things which you can do with them.
-</p>
-
-<H3><a name="Lisp_nn4">29.2.1 Additional Commandline Options </a></H3>
-
-
-<table summary="CFFI specific options">
-<tr>
- <th> CFFI specific options</th>
-</tr>
-
-<tr>
-<td>-generate-typedef</td>
-<td>If this option is given then defctype will be used to generate<br/>
- shortcuts according to the typedefs in the input.
-</td>
-</tr>
-
-<tr>
-<td>-[no]cwrap</td>
-<td>Turn on or turn off generation of an intermediate C file when<br/>
- creating a C interface. By default this is only done for C++ code.
-</td>
-</tr>
-
-<tr>
-<td>-[no]swig-lisp</td>
-<td>Turns on or off generation of code for helper lisp macro, functions,
- etc. which SWIG uses while generating wrappers. These macros, functions
- may still be used by generated wrapper code.
-</td>
-</tr>
-
-</table>
-
-<H3><a name="Lisp_nn5">29.2.2 Generating CFFI bindings</a></H3>
-
-
-<p>
-
-As we mentioned earlier the ideal way to use SWIG is to use interface
- files. To illustrate the use of it, let's assume that we have a
- file named <i>test.h</i> with the following C code:
-</p>
-
-<div class="code"><pre>
-#define y 5
-#define x (y &gt;&gt; 1)
-
-typedef int days;
-
-struct bar {
- short p, q;
- char a, b;
- int *z[1000];
- struct bar * n;
-};
-
-struct bar * my_struct;
-
-struct foo {
- int a;
- struct foo * b[100];
-};
-
-int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
-
-int func123(div_t * p, int **q[100], int r[][1000][10]);
-
-void lispsort_double (int n, double * array);
-
-enum color { RED, BLUE, GREEN};
-</pre></div>
-
-<p>
-Corresponding to this we will write a simple interface file:
-</p>
-
-<div class="code"><pre>
-%module test
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The generated SWIG Code will be:
-</p>
-
-<div class="targetlang"><pre>
-;;;SWIG wrapper code starts here
-
-(cl:defmacro defanonenum (&amp;body enums)
- "Converts anonymous enums to defconstants."
- `(cl:progn , @(cl:loop for value in enums
- for index = 0 then (cl:1+ index)
- when (cl:listp value) do (cl:setf index (cl:second value)
- value (cl:first value))
- collect `(cl:defconstant , value , index))))
-
-(cl:eval-when (:compile-toplevel :load-toplevel)
- (cl:unless (cl:fboundp 'swig-lispify)
- (cl:defun swig-lispify (name flag cl:&amp;optional (package cl:*package*))
- (cl:labels ((helper (lst last rest cl:&amp;aux (c (cl:car lst)))
- (cl:cond
- ((cl:null lst)
- rest)
- ((cl:upper-case-p c)
- (helper (cl:cdr lst) 'upper
- (cl:case last
- ((lower digit) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:lower-case-p c)
- (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
- ((cl:digit-char-p c)
- (helper (cl:cdr lst) 'digit
- (cl:case last
- ((upper lower) (cl:list* c #\- rest))
- (cl:t (cl:cons c rest)))))
- ((cl:char-equal c #\_)
- (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
- (cl:t
- (cl:error "Invalid character: ~A" c)))))
- (cl:let ((fix (cl:case flag
- ((constant enumvalue) "+")
- (variable "*")
- (cl:t ""))))
- (cl:intern
- (cl:concatenate
- 'cl:string
- fix
- (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
- fix)
- package))))))
-
-;;;SWIG wrapper code ends here
-
-
-(cl:defconstant y 5)
-
-(cl:defconstant x (cl:ash 5 -1))
-
-(cffi:defcstruct bar
- (p :short)
- (q :short)
- (a :char)
- (b :char)
- (z :pointer)
- (n :pointer))
-
-(cffi:defcvar ("my_struct" my_struct)
- :pointer)
-
-(cffi:defcstruct foo
- (a :int)
- (b :pointer))
-
-(cffi:defcfun ("pointer_func" pointer_func) :int
- (ClosureFun :pointer)
- (p :int))
-
-(cffi:defcfun ("func123" func123) :int
- (p :pointer)
- (q :pointer)
- (r :pointer))
-
-(cffi:defcfun ("lispsort_double" lispsort_double) :void
- (n :int)
- (array :pointer))
-
-(cffi:defcenum color
- :RED
- :BLUE
- :GREEN)
-</pre></div>
-
-<p>
- The <i>SWIG wrapper</i> code refers to the special code which SWIG
- may need to use while wrapping C code. You can turn on/off the
- generation of this code by using the <i>-[no]swig-lisp</i>
- option. You must have noticed that SWIG goes one extra step to
- ensure that CFFI does not do automatic lispification of the C
- function names. The reason SWIG does this is because quite often
- developers want to build a nice CLOS based lispy API, and this one
- to one correspondence between C function names and lisp function
- name helps.
-</p>
-
-<p> Maybe you want to have your own convention for generating lisp
- function names for corresponding C function names, or you just
- want to lispify the names, also, before we forget you want to
- export the generated lisp names. To do this, we will use the
- SWIG <a
- href="Customization.html#Customization_features">feature directive</a>.
-Let's edit the interface file such that the C type "div_t*" is changed
- to Lisp type ":my-pointer", we lispify all names,
- export everything, and do some more stuff.
-
-</p>
-<div class="code"><pre>
-%module test
-
-%typemap(cin) div_t* ":my-pointer"
-
-%feature("intern_function", "1");
-%feature("export");
-
-%feature("inline") lispsort_double;
-%feature("intern_function", "my-lispify") lispsort_double;
-%feature("export", package="'some-other-package") lispsort_double;
-
-%rename func123 renamed_cool_func;
-
-%ignore "pointer_func";
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The <i>typemap(cin)</i> ensures that for all arguments which are input
- to C with the type "div_t*", the ":my-pointer" type be
- used. Similarly <i>typemap(cout)</i> are used for all types which
- are returned from C.
-</p>
-<p>
-The feature <i>intern_function</i> ensures that all C names are
- interned using the <b>swig-lispify</b> function. The "1" given
- to the feature is optional. The use of feature like
- <i>%feature("intern_function", "1");</i> globally enables
- interning for everything. If you want to target a single
- function, or declaration then use the targeted version of
- feature, <i>%feature("intern_function", "my-lispify")
- lispsort_double;</i>, here we are using an additional feature
- which allows us to use our lispify function.
-</p>
-<p>The <i>export</i> feature allows us to export the symbols. If
- the <i>package</i> argument is given, then the symbol will be exported to
- the specified Lisp package. The <i>inline</i> feature declaims the
- declared function as inline. The <i>rename</i> directive allows us to
- change the name(it is useful when generating C wrapper code for handling
- overloaded functions). The <i>ignore</i> directive ignores a certain
- declaration.
-</p>
-<p>There are several other things which are possible, to see some
- example of usage of SWIG look at the Lispbuilder and wxCL
- projects. The generated code with 'noswig-lisp' option is:
-</p>
-
-<div class="targetlang"><pre>
-(cl:defconstant #.(swig-lispify "y" 'constant) 5)
-
-(cl:export '#.(swig-lispify "y" 'constant))
-
-(cl:defconstant #.(swig-lispify "x" 'constant) (cl:ash 5 -1))
-
-(cl:export '#.(swig-lispify "x" 'constant))
-
-(cffi:defcstruct #.(swig-lispify "bar" 'classname)
- (#.(swig-lispify "p" 'slotname) :short)
- (#.(swig-lispify "q" 'slotname) :short)
- (#.(swig-lispify "a" 'slotname) :char)
- (#.(swig-lispify "b" 'slotname) :char)
- (#.(swig-lispify "z" 'slotname) :pointer)
- (#.(swig-lispify "n" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "bar" 'classname))
-
-(cl:export '#.(swig-lispify "p" 'slotname))
-
-(cl:export '#.(swig-lispify "q" 'slotname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cl:export '#.(swig-lispify "z" 'slotname))
-
-(cl:export '#.(swig-lispify "n" 'slotname))
-
-(cffi:defcvar ("my_struct" #.(swig-lispify "my_struct" 'variable))
- :pointer)
-
-(cl:export '#.(swig-lispify "my_struct" 'variable))
-
-(cffi:defcstruct #.(swig-lispify "foo" 'classname)
- (#.(swig-lispify "a" 'slotname) :int)
- (#.(swig-lispify "b" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "foo" 'classname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cffi:defcfun ("renamed_cool_func" #.(swig-lispify "renamed_cool_func" 'function)) :int
- (p :my-pointer)
- (q :pointer)
- (r :pointer))
-
-(cl:export '#.(swig-lispify "renamed_cool_func" 'function))
-
-(cl:declaim (cl:inline #.(my-lispify "lispsort_double" 'function)))
-
-(cffi:defcfun ("lispsort_double" #.(my-lispify "lispsort_double" 'function)) :void
- (n :int)
- (array :pointer))
-
-(cl:export '#.(my-lispify "lispsort_double" 'function) 'some-other-package)
-
-(cffi:defcenum #.(swig-lispify "color" 'enumname)
- #.(swig-lispify "RED" 'enumvalue :keyword)
- #.(swig-lispify "BLUE" 'enumvalue :keyword)
- #.(swig-lispify "GREEN" 'enumvalue :keyword))
-
-(cl:export '#.(swig-lispify "color" 'enumname))
-
-</pre></div>
-
-<H3><a name="Lisp_nn6">29.2.3 Generating CFFI bindings for C++ code</a></H3>
-
-
-<p>This feature to SWIG (for CFFI) is very new and still far from
- complete. Pitch in with your patches, bug reports and feature
- requests to improve it.
-</p>
-<p> Generating bindings for C++ code, requires <i>-c++</i> option to be
- present and it first generates C binding which will wrap the C++
- code, and then generates the
- corresponding CFFI wrapper code. In the generated C wrapper
- code, you will often want to put your own C code, such as the
- code to include various files. This can be done by making use of
- "%{" and "%}" as shown below.
-</p>
-<div class="code"><pre>
-%{
- #include "Test/test.h"
-%}
-</pre></div>
-<p>
-Also, while parsing the C++ file and generating C wrapper code SWIG
- may need to be able to understand various symbols used in other
- header files. To help SWIG in doing this while ensuring that
- wrapper code is generated for the target file, use the "import"
- directive. The "include" directive specifies the target file for
- which wrapper code will be generated.
-</p>
-<div class="code"><pre>
-
-%import "ancillary/header.h"
-
-%include "target/header.h"
-
-</pre></div>
-<p>
-Various features which were available for C headers can also be used
- here. The target header which we are going to use here is:
-</p>
-<div class="code"><pre>
-namespace OpenDemo {
- class Test
- {
- public:
- float x;
- // constructors
- Test (void) {x = 0;}
- Test (float X) {x = X;}
-
- // vector addition
- Test operator+ (const Test&amp; v) const {return Test (x+v.x);}
-
- // length squared
- float lengthSquared (void) const {return this-&gt;dot (*this);}
-
- static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();}
-
- inline Test parallelComponent (const Test&amp; unitBasis) const {
- return unitBasis * projection;
- }
-
- Test setYtoZero (void) const {return Test (this-&gt;x);}
-
- static const Test zero;
- };
-
- inline Test operator* (float s, const Test&amp; v) {return v*s;}
-
- inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
- {
- return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
- }
-
- inline Test RandomUnitVectorOnXZPlane (void)
- {
- return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
- }
-}
-</pre></div>
-<p>The interface used is: </p>
-<div class="code"><pre>
-%module test
-%include "test.cpp"
-</pre></div>
-
-<p>
-SWIG generates 3 files, the first one is a C wrap which we don't show,
- the second is the plain CFFI wrapper which is as shown below:
-</p>
-<div class="targetlang"><pre>
-(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
- (self :pointer)
- (x :float))
-
-(cffi:defcfun ("_wrap_Test_x_get" Test_x_get) :float
- (self :pointer))
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_0" new_Test) :pointer)
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_1" new_Test) :pointer
- (X :float))
-
-(cffi:defcfun ("_wrap_Test___add__" Test___add__) :pointer
- (self :pointer)
- (v :pointer))
-
-(cffi:defcfun ("_wrap_Test_lengthSquared" Test_lengthSquared) :float
- (self :pointer))
-
-(cffi:defcfun ("_wrap_Test_distance" Test_distance) :float
- (a :pointer)
- (b :pointer))
-
-(cffi:defcfun ("_wrap_Test_parallelComponent" Test_parallelComponent) :pointer
- (self :pointer)
- (unitBasis :pointer))
-
-(cffi:defcfun ("_wrap_Test_setYtoZero" Test_setYtoZero) :pointer
- (self :pointer))
-
-(cffi:defcvar ("Test_zero" Test_zero)
- :pointer)
-
-(cffi:defcfun ("_wrap_delete_Test" delete_Test) :void
- (self :pointer))
-
-(cffi:defcfun ("_wrap___mul__" __mul__) :pointer
- (s :float)
- (v :pointer))
-
-(cffi:defcfun ("_wrap___lshift__" __lshift__) :pointer
- (o :pointer)
- (v :pointer))
-
-(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
-</pre></div>
-
-<p>
-The output is pretty good but it fails in disambiguating overloaded
- functions such as the constructor, in this case. One way of
- resolving this problem is to make the interface use the rename
- directiv, but hopefully there are better solutions.
- In addition SWIG also generates, a CLOS file
-</p>
-
-
-<div class="targetlang"><pre>
-(clos:defclass test()
- ((ff :reader ff-pointer)))
-
-(clos:defmethod (cl:setf x) (arg0 (obj test))
- (Test_x_set (ff-pointer obj) arg0))
-
-(clos:defmethod x ((obj test))
- (Test_x_get (ff-pointer obj)))
-
-(cl:shadow "+")
-(clos:defmethod + ((obj test) (self test) (v test))
- (Test___add__ (ff-pointer obj) (ff-pointer self) (ff-pointer v)))
-
-(clos:defmethod length-squared ((obj test) (self test))
- (Test_lengthSquared (ff-pointer obj) (ff-pointer self)))
-
-(clos:defmethod parallel-component ((obj test) (self test) (unitBasis test))
- (Test_parallelComponent (ff-pointer obj) (ff-pointer self) (ff-pointer unitBasis)))
-
-(clos:defmethod set-yto-zero ((obj test) (self test))
- (Test_setYtoZero (ff-pointer obj) (ff-pointer self)))
-</pre></div>
-
-<p>I agree that the CFFI C++ module needs lot more work. But I hope it
- provides a starting point, on which you can base your work of
- importing C++ libraries to Lisp.
-</p>
-<p>
-If you have any questions, suggestions, patches, etc., related to CFFI
- module feel free to contact us on the SWIG mailing list, and
- also please add a "[CFFI]" tag in the subject line.
-
-<H3><a name="Lisp_nn7">29.2.4 Inserting user code into generated files</a></H3>
-
-
-<p>
-It is often necessary to <a href="SWIG.html#SWIG_nn40">include user-defined code</a>
-into the automatically generated interface files. For example, when building
-a C++ interface, example_wrap.cxx will likely not compile unless
-you add a <tt>#include "header.h"</tt> directive. This can be done
-using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
-</p>
-
-<div class="code">
-<pre>
-%module example
-
-%{
-#include "header.h"
-%}
-
-%include "header.h"
-
-int fact(int n);
-</pre>
-</div>
-
-<p>
-Additional sections have been added for inserting into the
-generated lisp interface file:
-</p>
-<ul>
- <li><tt>lisphead</tt> - inserts before type declarations</li>
- <li><tt>swiglisp</tt> - inserts after type declarations according to
- where it appears in the .i file</li>
-</ul>
-<p>
-Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
-<tt>%insert("header") %{ ... %}</tt>.
-</p>
-
-
-</body>
-</html>