diff --git a/CHANGES.current b/CHANGES.current
index 3968e56ee..a4745716e 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,17 @@
Version 1.3.25 (In progress)
============================
+04/05/2005: wuzzeb (John Lenz)
+ [Chicken]
+ + Added Examples/chicken/egg, an example on how to build a chicken
+ extension library in the form of an egg. Also updated the
+ documentation on the different linking options.
+
+ + chicken test-suite now has support to check SWIG with the -proxy
+ argument if there exists a _proxy_runme.ss file.
+
+ + More fixes for overloaded functions and -proxy
+
03/31/2005: wsfulton
Turned on extra template features for all languages which were
previously only available to Python.
diff --git a/Doc/Manual/Chicken.html b/Doc/Manual/Chicken.html
index bf132b987..0ef9bc34d 100644
--- a/Doc/Manual/Chicken.html
+++ b/Doc/Manual/Chicken.html
@@ -104,11 +104,14 @@
generation improvements, part of the wrapper is direct CHICKEN
function calls (example_wrap.c ) and part is CHICKEN
Scheme (example.scm ). The basic Scheme code must
- be compiled to C using your system's CHICKEN compiler.
+ be compiled to C using your system's CHICKEN compiler or
+ both files can be compiled directly using the much simpler csc .
@@ -317,21 +321,7 @@
-
17.4 Compilation
-
-
-
- Please refer to CHICKEN - A practical and portable Scheme
- system - User's manual for detailed help on how to compile
- C code for use in a CHICKEN program. Briefly, to compile C
- code, be sure to add `chicken-config -cflags` or
- `chicken-config -shared -cflags` to your compiler
- options. Use the -shared option if you want to create
- a dynamically loadable module. You might also want to use the
- much simpler csc or csc.bat .
-
-
-
17.5 Linkage
+
17.4 Linkage
@@ -342,51 +332,139 @@
-extra-libs -libs` or `chicken-config -shared
-extra-libs -libs` to your linker options. Use the
-shared option if you want to create a dynamically
- loadable module.
+ loadable module. You might also want to use the much simpler
+ csc or csc.bat .
-
17.5.1 Shared library
+
Each scheme file that is generated
+ by SWIG contains (declare (uses modname )). This means that to load the
+ module from scheme code, the code must include (declare (uses modname )).
+
-
- The easiest way to use SWIG and CHICKEN is to use the csc compiler
- wrapper provided by CHICKEN. Assume you have a SWIG interface file
- in example.i and the C functions being wrapped are in example_impl.c.
-
+
17.4.1 Static binary or shared library linked at compile time
+
+
+
We can easily use csc to build a static binary.
$ swig -chicken example.i
-$ csc -svk example.scm example_impl.c example_wrap.c
-$ csi example.so test_script.scm
-
-
-
-
- You must be careful not to name the example_impl.c file example.c because
- when compiling example.scm, csc compiles that into example.c!
-
-
-
- The test_script.scm should have (load-library 'example "example.so")
- and (declare (uses example)). As well, the path to example.so should
- be accessable to the loader. You might need to set LD_LIBRARY_PATH.
-
-
-
17.5.2 Static binary
-
-
-
Again, we can easily use csc to build a binary.
-
-
-
-$ swig -chicken example.i
-$ csc -vk example.scm example_impl.c example_wrap.c test_script.scm -o example
+$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example
$ ./example
-
17.6 Typemaps
+
Similar to the above, any number of module.scm files could be compiled
+into a shared library, and then that shared library linked when compiling the
+main application.
+
+
+
+$ swig -chicken example.i
+$ csc -sv example.scm example_wrap.c example_impl.c -o example.so
+
+
+
+
The exmaple.so file can then linked with test_script.scm when it
+is compiled, in which case test_script.scm must have (declare (uses example)).
+Multiple SWIG modules could have been linked into example.so and each
+one accessed with a (declare (uses ... )).
+
+
+
+
+$ csc -v test_script.scm -lexample
+
+
+
+
An alternative is the test_script.scm can have the code (load-library 'example "example.so"),
+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 csi .
+
+
+
17.4.2 Building chicken extension libraries
+
+
+
Building a shared library like in the above section only works if the library
+is linked at compile time with a script containing (declare (uses ...)) or is
+loaded explictetly with (load-library 'example "example.so"). It is
+not the format that chicken expects for extension libraries and eggs. The problem is the
+(declare (unit modname )) inside the modname.scm file. There are
+two possible solutions to this.
+
+
First, SWIG accepts a -nounit argument, in which case the (declare (unit modname ))
+is not generated. Then, the modname.scm and modname_wrap.c files must be compiled into
+their own shared library.
+
+
+
+$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
+
+
+
+
This library can then be loaded by scheme code with the (require 'modname) function.
+See
+Loading-extension-libraries in the eval unit inside the Chicken manual for more information.
+
+
Another alternative is to run SWIG normally and create a scheme file that contains (declare (uses modname ))
+and then compile that file into the shared library as well. For example, inside the mod_load.scm file,
+
+
+
+(declare (uses mod1))
+(declare (uses mod2))
+
+
+
+
Which would then be compiled with
+
+
+
+$ 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
+
+
+
+
Then the extension library can be loaded with (require 'mod). As we can see here,
+mod_load.scm contains the code that gets exectued 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
+%import
+
+
In either method, the files that are compiled into the shared library could also be
+packaged into an egg. The mod1_wrap.c and mod2_wrap.c 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.
+
+
See the Examples/chicken/egg directory in the SWIG source for an example that builds
+two eggs, one using the first method and one using the second method.
+
+
17.4.3 Linking multiple SWIG modules with TinyCLOS
+
+
Linking together multiple modules that share type information using the %import
+directive while also using -proxy is more complicated. For example, if mod2.i imports mod1.i , then the
+mod2.scm file contains references to symbols declared in mod1.scm ,
+and thus a (declare (uses mod1 )) or (require 'mod1 ) must be exported
+to the top of mod2.scm . By default, when SWIG encounters an %import "modname.i" directive,
+it exports (declare (uses modname )) into the scm file. This works fine unless mod1 was compiled with
+the -nounit argument or was compiled into an extension library with other modules under a different name.
+
+
One option is to override the automatic generation of (declare (uses mod1))
+by passing the -noclosuses option to SWIG when compiling mod2.i .
+SWIG then provides the %insert(closprefix) %{ %} directive. Any scheme code inside that directive is inserted into the
+generated .scm file, and if mod1 was compiled with -nounit , the directive should contain (require 'mod1).
+This option allows for mixed loading as well, where some modules are imported with (declare (uses modname ))
+(which means they were compiled without -nounit) and some are imported with (require 'modname).
+
+
The other option is to use the second idea in the above section. Compile all the modules normally, without any
+%insert(closprefix), -nounit , or -noclosuses . Then the modules will import each other correctly
+with (declare (uses ...)).
+To create an extension library or an egg, just create a module_load.scm file that (declare (uses ...))
+all the modules.
+
+
17.5 Typemaps
@@ -395,7 +473,7 @@ $ ./example
Lib/chicken/chicken.swg.
-
17.7 Pointers
+
17.6 Pointers
@@ -428,7 +506,7 @@ $ ./example
type. flags is either zero or SWIG_POINTER_DISOWN (see below).
-
17.7.1 Garbage collection
+
17.6.1 Garbage collection
If the owner flag passed to SWIG_NewPointerObj is 1, NewPointerObj will add a
@@ -459,7 +537,7 @@ $ ./example
must be called manually.
-
17.8 Unsupported features and known problems
+
17.7 Unsupported features and known problems
diff --git a/Examples/chicken/README b/Examples/chicken/README
index 2829766f2..fb518ce02 100644
--- a/Examples/chicken/README
+++ b/Examples/chicken/README
@@ -2,6 +2,7 @@ This directory contains examples for CHICKEN.
class -- illustrates the shadow-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
diff --git a/Examples/chicken/egg/Makefile b/Examples/chicken/egg/Makefile
new file mode 100644
index 000000000..bdf71b104
--- /dev/null
+++ b/Examples/chicken/egg/Makefile
@@ -0,0 +1,39 @@
+SWIG = ../../../preinst-swig
+
+all: 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
+
+# complie the single module with -nounit
+single_wrap.cxx: single.i
+ $(SWIG) -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
+ $(SWIG) -chicken -c++ -proxy mod1.i
+
+mod2_wrap.cxx: mod2.i
+ $(SWIG) -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
+
+check:
+ cd eggs/install && csi ../../test.scm
diff --git a/Examples/chicken/egg/README b/Examples/chicken/egg/README
new file mode 100644
index 000000000..b5df0e631
--- /dev/null
+++ b/Examples/chicken/egg/README
@@ -0,0 +1,19 @@
+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.
diff --git a/Examples/chicken/egg/mod1.i b/Examples/chicken/egg/mod1.i
new file mode 100644
index 000000000..6a2940b89
--- /dev/null
+++ b/Examples/chicken/egg/mod1.i
@@ -0,0 +1,8 @@
+%module mod1
+
+%inline %{
+class Bar {
+ public:
+ int b;
+};
+%}
diff --git a/Examples/chicken/egg/mod2.i b/Examples/chicken/egg/mod2.i
new file mode 100644
index 000000000..e9ae4a6a8
--- /dev/null
+++ b/Examples/chicken/egg/mod2.i
@@ -0,0 +1,17 @@
+%module mod2
+
+%import "mod1.i"
+
+%{
+class Bar {
+ public:
+ int b;
+};
+%}
+
+%inline %{
+ class Bar2 : public Bar {
+ public:
+ int c;
+ };
+%}
diff --git a/Examples/chicken/egg/multi.setup b/Examples/chicken/egg/multi.setup
new file mode 100644
index 000000000..95aeb001c
--- /dev/null
+++ b/Examples/chicken/egg/multi.setup
@@ -0,0 +1,2 @@
+(run (csc -s -o multi.so multi_init.scm mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx))
+(install-extension 'multi '("multi.so"))
diff --git a/Examples/chicken/egg/multi_init.scm b/Examples/chicken/egg/multi_init.scm
new file mode 100644
index 000000000..600491d5b
--- /dev/null
+++ b/Examples/chicken/egg/multi_init.scm
@@ -0,0 +1,2 @@
+(declare (uses mod1))
+(declare (uses mod2))
diff --git a/Examples/chicken/egg/single.i b/Examples/chicken/egg/single.i
new file mode 100644
index 000000000..46266b4bf
--- /dev/null
+++ b/Examples/chicken/egg/single.i
@@ -0,0 +1,8 @@
+%module single
+
+%inline %{
+class Foo {
+ public:
+ int a;
+};
+%}
diff --git a/Examples/chicken/egg/single.setup b/Examples/chicken/egg/single.setup
new file mode 100644
index 000000000..4b503ec21
--- /dev/null
+++ b/Examples/chicken/egg/single.setup
@@ -0,0 +1,2 @@
+(run (csc -s -o single.so single.scm single_wrap.cxx))
+(install-extension 'single '("single.so"))
diff --git a/Examples/chicken/egg/test.scm b/Examples/chicken/egg/test.scm
new file mode 100644
index 000000000..4ec94ed18
--- /dev/null
+++ b/Examples/chicken/egg/test.scm
@@ -0,0 +1,18 @@
+(require-extension single)
+(require-extension multi)
+
+(define f (make ))
+(slot-set! f 'a 3)
+(print (slot-ref f 'a))
+
+(define b (make ))
+(slot-set! b 'b 2)
+(print (slot-ref b 'b))
+
+(define b2 (make ))
+(slot-set! b2 'b 4)
+(slot-set! b2 'c 6)
+(print (slot-ref b2 'b))
+(print (slot-ref b2 'c))
+
+(exit 0)
diff --git a/Examples/test-suite/chicken/Makefile.in b/Examples/test-suite/chicken/Makefile.in
index dc329a2ae..351ba386b 100644
--- a/Examples/test-suite/chicken/Makefile.in
+++ b/Examples/test-suite/chicken/Makefile.in
@@ -6,6 +6,7 @@
LANGUAGE = chicken
VARIANT =
SCRIPTSUFFIX = _runme.ss
+PROXYSUFFIX = _runme_proxy.ss
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
@@ -24,11 +25,17 @@ SWIGOPT +=
$(setup) \
($(swig_and_compile_cpp); ) && \
$(run_testcase)
+ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then ( \
+ $(MAKE) $*.cppproxy; ) \
+ fi;
%.ctest:
$(setup) \
($(swig_and_compile_c); ) && \
$(run_testcase)
+ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then ( \
+ $(MAKE) $*.cproxy; ) \
+ fi;
%.multicpptest:
$(setup) \
@@ -42,6 +49,22 @@ run_testcase = \
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(CHICKEN_CSI) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
fi;
+# If there exists a PROXYSUFFIX runme file, we also generate the wrapper
+# with the -proxy argument
+%.cppproxy: SWIGOPT += -proxy
+%.cppproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
+%.cppproxy:
+ echo "Checking testcase $* (with run test) under chicken with -proxy"; \
+ ($(swig_and_compile_cpp); ) && \
+ $(run_testcase)
+
+%.cproxy: SWIGOPT += -proxy
+%.cproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
+%.cproxy:
+ echo "Checking testcase $* (with run test) under chicken with -proxy"; \
+ ($(swig_and_compile_c); ) && \
+ $(run_testcase)
+
# Clean
%.clean:
diff --git a/Examples/test-suite/chicken/README b/Examples/test-suite/chicken/README
index a090e3cc2..ba32bb464 100644
--- a/Examples/test-suite/chicken/README
+++ b/Examples/test-suite/chicken/README
@@ -5,3 +5,7 @@ NOTE: I had to use _runme.ss becuase otherwise it would be hard to implement mak
Since when SWIG runs it generates an example.scm file for every test, to clean those files
I needed to add a rm -f *.scm to make clean. But we don't want the runme scripts to
dissappear as well!
+
+Any testcases which have _runme_proxy.ss appended after the testcase name will be detected
+and run with the -proxy argument passed to SWIG. SWIG will not be run with the -unhide-primitive
+option, so the _runme_proxy.ss file must use only the tinyclos exported interface.
diff --git a/Examples/test-suite/chicken/newobject2_runme.ss b/Examples/test-suite/chicken/newobject2_runme.ss
index 409e65888..b73446a47 100644
--- a/Examples/test-suite/chicken/newobject2_runme.ss
+++ b/Examples/test-suite/chicken/newobject2_runme.ss
@@ -1,20 +1,29 @@
(load-library 'newobject2 "newobject2.so")
-(define f (make ))
+(define f (new-Foo))
-(slot-set! f 'dummy 14)
-(if (not (= (slot-ref f 'dummy) 14))
+(Foo-dummy-set f 14)
+(if (not (= (Foo-dummy-get f) 14))
(error "Bad dummy value"))
+(if (not (= (fooCount) 0))
+ (error "Bad foo count 1"))
+
(define f2 (makeFoo))
-(slot-set! f2 'dummy 16)
-(if (not (= (slot-ref f2 'dummy) 16))
+(if (not (= (fooCount) 1))
+ (error "Bad foo count 2"))
+
+(Foo-dummy-set f2 16)
+(if (not (= (Foo-dummy-get f2) 16))
(error "Bad dummy value for f2"))
(set! f #f)
(set! f2 #f)
-(gc)
+(gc #t)
+
+(if (not (= (fooCount) -1))
+ (error "Bad foo count 3"))
(exit 0)
diff --git a/Examples/test-suite/chicken/newobject2_runme_proxy.ss b/Examples/test-suite/chicken/newobject2_runme_proxy.ss
new file mode 100644
index 000000000..42bc300f3
--- /dev/null
+++ b/Examples/test-suite/chicken/newobject2_runme_proxy.ss
@@ -0,0 +1,29 @@
+(load-library 'newobject2 "newobject2.so")
+
+(define f (make ))
+
+(slot-set! f 'dummy 14)
+(if (not (= (slot-ref f 'dummy) 14))
+ (error "Bad dummy value"))
+
+(if (not (= (fooCount) 0))
+ (error "Bad foo count 1"))
+
+(define f2 (makeFoo))
+
+(if (not (= (fooCount) 1))
+ (error "Bad foo count 2"))
+
+(slot-set! f2 'dummy 16)
+(if (not (= (slot-ref f2 'dummy) 16))
+ (error "Bad dummy value for f2"))
+
+(set! f #f)
+(set! f2 #f)
+
+(gc #t)
+
+(if (not (= (fooCount) -1))
+ (error "Bad foo count 3"))
+
+(exit 0)
diff --git a/Lib/cdata.i b/Lib/cdata.i
index 4e098f163..37fb43455 100644
--- a/Lib/cdata.i
+++ b/Lib/cdata.i
@@ -45,6 +45,12 @@ typedef struct SWIGCDATA {
$result = gh_str2scm($1.data,$1.len);
}
%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH);
+#elif SWIGCHICKEN
+%typemap(out) SWIGCDATA {
+ C_word *string_space = C_alloc(C_SIZEOF_STRING($1.len));
+ $result = C_string(&string_space, $1.len, $1.data);
+}
+%typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH);
#else
%echo "cdata.i module not supported."
#endif
diff --git a/Lib/chicken/swigclosprefix.scm b/Lib/chicken/swigclosprefix.scm
index 14cd52f4d..343a079f7 100644
--- a/Lib/chicken/swigclosprefix.scm
+++ b/Lib/chicken/swigclosprefix.scm
@@ -1,4 +1,4 @@
-(declare (hide swig-initialize swig-initialize-return))
+(declare (hide swig-initialize swig-init-return))
(define (swig-initialize obj initargs create)
(slot-set! obj 'swig-this
diff --git a/Source/Modules/chicken.cxx b/Source/Modules/chicken.cxx
index 8d70a60a6..9f93138bc 100644
--- a/Source/Modules/chicken.cxx
+++ b/Source/Modules/chicken.cxx
@@ -56,27 +56,34 @@ static String *swigtype_ptr = 0;
static String *f_sym_size = 0;
static String *closcode = 0;
+/* some options */
+static int declare_unit = 1;
+static int no_collection = 0;
+
/* C++ Support + Clos Classes */
static int clos = 0;
static String *class_name = 0;
static String *short_class_name = 0;
-static String *clos_class_methods = 0;
+
+/* sections of the clos code */
+static String *clos_class_defines = 0;
+static String *clos_methods = 0;
+
static int in_class = 0;
static int have_constructor = 0;
-static String *constructor_name = 0;
static bool exporting_destructor = false;
+static String *constructor_name = 0;
+static String *memberfunction_name = 0;
+
static int useclassprefix = 0;
static String *closprefix = 0;
-static String *memberfunction_name = 0;
static int hide_primitive = 1;
static Hash *primitive_names = 0;
-static int declare_unit = 1;
-static int no_collection = 0;
+/* Used for overloading constructors */
static int has_constructor_args = 0;
static List *constructor_arg_types = 0;
static String *constructor_dispatch = 0;
-static String *constructor_dispatch_func = 0;
static Hash *overload_parameter_lists = 0;
@@ -88,7 +95,6 @@ public:
virtual int functionWrapper(Node *n);
virtual int variableWrapper(Node *n);
virtual int constantWrapper(Node *n);
- virtual int classDeclaration(Node *n);
virtual int classHandler(Node *n);
virtual int memberfunctionHandler(Node *n);
virtual int membervariableHandler(Node *n);
@@ -229,6 +235,8 @@ CHICKEN::top(Node *n)
Swig_register_filebyname("closprefix", closhelpers);
closcode = NewString("");
+ clos_class_defines = NewString("");
+ clos_methods = NewString("");
Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
Swig_banner(f_runtime);
@@ -290,6 +298,8 @@ CHICKEN::top(Node *n)
Replaceall(closhelpers,"$module", scmmodule);
Printf (f_scm, "%s\n", closhelpers);
Printf (f_scm, "%s\n", closcode);
+ Printf (f_scm, "%s\n", clos_class_defines);
+ Printf (f_scm, "%s\n", clos_methods);
}
Printf(f_scm, "%s\n", chickentext);
@@ -313,6 +323,10 @@ CHICKEN::top(Node *n)
Delete(closhelpers);
Delete(overload_parameter_lists);
+ Delete(closcode);
+ Delete(clos_class_defines);
+ Delete(clos_methods);
+
/* Close all of the files */
Delete(primitive_names);
Delete(scmmodule);
@@ -449,10 +463,11 @@ CHICKEN::functionWrapper(Node *n)
if (i < num_required) {
if (strcmp("void", Char(pt)) != 0) {
Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"), checkNodeClass);
- String *closclassname = (class_node == NULL) ? NULL : Getattr(class_node, "chicken:closclassname");
- if (closclassname) {
- Append(function_arg_types, closclassname);
+ if (class_node) {
+ String *class_name = NewStringf("<%s>", Getattr(class_node, "sym:name"));
+ Append(function_arg_types, class_name);
any_specialized_arg = true;
+ Delete(class_name);
} else {
Append(function_arg_types, "^^##primitive$$");
}
@@ -625,11 +640,7 @@ CHICKEN::functionWrapper(Node *n)
1);
Delete(fmt);
}
- if (in_class) {
- Printv(clos_class_methods, method_def, NIL);
- } else {
- Printv(closcode, method_def, NIL);
- }
+ Printv(clos_methods, method_def, NIL);
Delete(clos_name);
Delete(method_def);
}
@@ -645,28 +656,8 @@ CHICKEN::functionWrapper(Node *n)
flist = NewList();
Setattr(overload_parameter_lists, scmname, flist);
}
- /* remove all primitive arguments from the end of the list */
- List *nlst = NewList();
- List *plst = NewList();
- Iterator i;
- for (i = First(function_arg_types); i.item; i = Next(i)) {
- if (Strcmp(i.item, "^^##optional$$") == 0) {
- /* skip it */
- } else if (Strcmp(i.item, "^^##primitive$$") == 0) {
- Append(plst, i.item);
- } else {
- /* append plst onto nlst */
- Iterator j;
- for (j = First(plst); j.item; j = Next(j)) {
- Append(nlst, j.item);
- }
- Delete(plst);
- plst = NewList();
- Append(nlst, i.item);
- }
- }
- Delete(plst);
- Append(flist, nlst);
+
+ Append(flist, Copy(function_arg_types));
if (!Getattr(n,"sym:nextSibling")) {
dispatchFunction(n);
@@ -810,7 +801,7 @@ CHICKEN::variableWrapper(Node *n) {
String *class_name = SwigType_typedef_resolve_all(SwigType_base(t));
String *clos_name = chickenNameMapping(scmname, (char *)"");
/* Simply re-export the procedure */
- Printv(closcode, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
Delete(class_name);
Delete(clos_name);
}
@@ -975,7 +966,7 @@ CHICKEN::constantWrapper(Node *n)
if (!in_class) {
String *clos_name = chickenNameMapping(scmname, (char *)"");
- Printv(closcode, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
Delete(clos_name);
}
@@ -998,21 +989,12 @@ CHICKEN::constantWrapper(Node *n)
return SWIG_OK;
}
-int
-CHICKEN::classDeclaration(Node *n)
-{
- String *class_name = NewStringf("<%s>", Getattr(n, "sym:name"));
- Setattr(n, "chicken:closclassname", class_name);
- return Language::classDeclaration(n);
-}
-
int
CHICKEN::classHandler(Node *n)
{
/* Create new strings for building up a wrapper function */
have_constructor = 0;
constructor_dispatch = 0;
- constructor_dispatch_func = 0;
constructor_name = 0;
class_name = NewString("");
@@ -1043,17 +1025,17 @@ CHICKEN::classHandler(Node *n)
String *scmmod = NewString(module);
Replaceall(scmmod, "_", "-");
- Printv(closcode,"(define ", class_name, "\n",
+ Printv(clos_class_defines,"(define ", class_name, "\n",
" (make 'name '", class_name, "\n", NIL);
Delete(scmmod);
if (Len(base_class) > 2) {
- Printv(closcode," 'direct-supers (list ", base_class, ")\n", NIL);
+ Printv(clos_class_defines," 'direct-supers (list ", base_class, ")\n", NIL);
} else {
- Printv(closcode," 'direct-supers (list )\n", NIL);
+ Printv(clos_class_defines," 'direct-supers (list )\n", NIL);
}
- Printf(closcode, " 'direct-slots (list 'swig-this\n");
+ Printf(clos_class_defines, " 'direct-slots (list 'swig-this\n");
String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
@@ -1066,22 +1048,15 @@ CHICKEN::classHandler(Node *n)
SwigType_remember(ct);
/* Emit all of the members */
- clos_class_methods = NewString("");
in_class = 1;
Language::classHandler(n);
in_class = 0;
- Printf(closcode, ")))\n");
-
- if (constructor_dispatch_func) {
- Printf(closcode, "%s", constructor_dispatch_func);
- Delete(constructor_dispatch_func);
- constructor_dispatch_func = 0;
- }
+ Printf(clos_class_defines, ")))\n\n");
if (have_constructor) {
- Printv(closcode, "(define-method (initialize (obj ", class_name, ") initargs)\n",
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n",
" (call-next-method)\n",
" (swig-initialize obj initargs ", NIL);
if (constructor_arg_types) {
@@ -1089,31 +1064,27 @@ CHICKEN::classHandler(Node *n)
"(lambda (%s) %s)",
chickenPrimitiveName(constructor_name),
0);
- Printf(closcode, "%s", func_call);
+ Printf(clos_methods, "%s", func_call);
Delete(func_call);
Delete(constructor_arg_types);
constructor_arg_types = 0;
} else if (constructor_dispatch) {
- Printf(closcode, "%s", constructor_dispatch);
+ Printf(clos_methods, "%s", constructor_dispatch);
Delete(constructor_dispatch);
constructor_dispatch = 0;
} else {
- Printf(closcode, "%s", chickenPrimitiveName(constructor_name));
+ Printf(clos_methods, "%s", chickenPrimitiveName(constructor_name));
}
- Printf(closcode, ")\n)\n");
+ Printf(clos_methods, ")\n)\n");
Delete(constructor_name);
constructor_name = 0;
} else {
- Printv(closcode, "(define-method (initialize (obj ", class_name, ") initargs)\n",
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n",
" (call-next-method)\n",
" (swig-initialize obj initargs (lambda x #f)))\n",
NIL);
}
- Printf(closcode, "%s\n", clos_class_methods);
- Delete(clos_class_methods);
- clos_class_methods = 0;
-
/* export class initialization function */
if (clos) {
String *funcname = NewString(mangled_classname);
@@ -1132,7 +1103,7 @@ CHICKEN::classHandler(Node *n)
"}\n", NIL);
addMethod(closfuncname, funcname);
- Printv(closcode, "(", chickenPrimitiveName(closfuncname), " (lambda (x) (make ", class_name, " 'swig-this x)))\n", NIL);
+ Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x) (make ", class_name, " 'swig-this x)))\n\n", NIL);
Delete(closfuncname);
Delete(funcname);
@@ -1173,7 +1144,7 @@ CHICKEN::staticmemberfunctionHandler(Node *n)
String *proc = NewString(iname);
Replaceall(proc, "_", "-");
- memberfunction_name = chickenNameMapping(proc, short_class_name);
+ memberfunction_name = NewStringf("%s-%s", short_class_name, proc);
Language::staticmemberfunctionHandler(n);
Delete(memberfunction_name);
memberfunction_name = NULL;
@@ -1194,21 +1165,20 @@ CHICKEN::membervariableHandler(Node *n)
Replaceall(proc,"_","-");
Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab"));
- String *closclassname = (class_node == NULL) ? NULL : Getattr(class_node, "chicken:closclassname");
String *getfunc = NewStringf("%s-%s-get", short_class_name, proc);
String *setfunc = NewStringf("%s-%s-set", short_class_name, proc);
- Printv(closcode," (list '", proc, " ':swig-virtual ':swig-get ", chickenPrimitiveName(getfunc), NIL);
+ Printv(clos_class_defines," (list '", proc, " ':swig-virtual ':swig-get ", chickenPrimitiveName(getfunc), NIL);
if (!Getattr(n,"feature:immutable")) {
- if (closclassname) {
- Printv(closcode, " ':swig-set (lambda (x y) (", chickenPrimitiveName(setfunc), " x (slot-ref y 'swig-this))))\n", NIL);
+ if (class_node) {
+ Printv(clos_class_defines, " ':swig-set (lambda (x y) (", chickenPrimitiveName(setfunc), " x (slot-ref y 'swig-this))))\n", NIL);
} else {
- Printv(closcode, " ':swig-set ", chickenPrimitiveName(setfunc), ")\n", NIL);
+ Printv(clos_class_defines, " ':swig-set ", chickenPrimitiveName(setfunc), ")\n", NIL);
}
} else {
- Printf(closcode, ")\n");
+ Printf(clos_class_defines, ")\n");
}
Delete(proc);
@@ -1229,15 +1199,14 @@ CHICKEN::staticmembervariableHandler(Node *n)
String *closprocname = chickenNameMapping(proc, short_class_name);
Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab"));
- String *closclassname = (class_node == NULL) ? NULL : Getattr(class_node, "chicken:closclassname");
String *primfunc = NewStringf("%s-%s", short_class_name, proc);
- if (closclassname) {
- Printv(clos_class_methods, "(define (", closprocname, " . lst) (if (null? lst) (", chickenPrimitiveName(primfunc), ") (",
+ if (class_node) {
+ Printv(clos_methods, "(define (", closprocname, " . lst) (if (null? lst) (", chickenPrimitiveName(primfunc), ") (",
chickenPrimitiveName(primfunc), " (slot-ref (car lst) 'swig-this))))\n", NIL);
} else {
- Printv(clos_class_methods, "(define ", closprocname, " ", chickenPrimitiveName(primfunc), ")\n", NIL);
+ Printv(clos_methods, "(define ", closprocname, " ", chickenPrimitiveName(primfunc), ")\n", NIL);
}
Delete(closprocname);
@@ -1298,14 +1267,21 @@ String *CHICKEN::buildClosFunctionCall(List *types, char *format, String_or_char
Iterator arg_type;
int arg_count = 0;
int optional_arguments = 0;
+ int first_argument = 1;
for (arg_type = First(types); arg_type.item; arg_type = Next(arg_type)) {
if (Strcmp(arg_type.item, "^^##optional$$") == 0) {
optional_arguments = 1;
} else if (Strcmp(arg_type.item, "^^##primitive$$") == 0) {
- Printf(method_signature, " arg%i", arg_count);
+ if (first_argument)
+ Printf(method_signature, " (arg%i )", arg_count);
+ else
+ Printf(method_signature, " arg%i", arg_count);
+
Printf(func_args, " arg%i", arg_count);
+ first_argument = 0;
} else {
+ first_argument = 0;
if (method_specialize) {
Printf(method_signature, " (arg%i %s)", arg_count, arg_type.item);
} else {
@@ -1447,7 +1423,7 @@ CHICKEN::dispatchFunction(Node *n)
constructor_dispatch = NewStringf("%s@SWIG@new@dispatch", short_class_name);
clos_name = Copy(constructor_dispatch);
construct = 1;
- constructor_dispatch_func = NewStringf("(declare (hide %s))\n", clos_name);
+ Printf(clos_methods, "(declare (hide %s))\n", clos_name);
} else if (in_class)
clos_name = NewString(memberfunction_name);
else
@@ -1455,51 +1431,54 @@ CHICKEN::dispatchFunction(Node *n)
Iterator f;
List *prev = 0;
- int has_all_prim = 0;
+ int has_empty_call = 0;
+ int all_primitive = 1;
+
+ /* first check for duplicates and an empty call */
+ String *method_name = NewString(clos_name);
+ String *newlist = NewList();
for (f = First(flist); f.item; f = Next(f)) {
/* check if cur is a duplicate of prev */
if (prev && compareTypeLists(f.item, prev) == 0) {
Delete(f.item);
- continue;
- }
- if (Len(f.item) == 0) {
- has_all_prim = 1;
+ } else if (Len(f.item) == 0) {
+ has_empty_call = 1;
+ Delete(method_name);
+ method_name = NewStringf("%s@SWIG@multireal", clos_name);
Delete(f.item);
- continue;
+ } else {
+ Append(newlist, f.item);
+ prev = f.item;
+ Iterator j;
+ for (j = First(f.item); j.item; j = Next(j)) {
+ if (Strcmp(j.item, "^^##optional$$") != 0 && Strcmp(j.item, "^^##primitive$$") != 0)
+ all_primitive = 0;
+ }
}
- /* now export clos code for argument */
- List *n = NewList();
- n = Copy(f.item);
- Push(n, "^^##optional$$");
- String *fmt = NewStringf("(define-method (%s %%s) %%s)\n", clos_name);
- String *func_call = buildClosFunctionCall(n, Char(fmt), chickenPrimitiveName(scmname), 1);
-
- if (construct)
- Printf(constructor_dispatch_func, "%s", func_call);
- else if (in_class)
- Printf(clos_class_methods, "%s", func_call);
- else
- Printf(closcode, "%s", func_call);
-
- Delete(func_call);
- Delete(n);
-
- Delete(prev);
- prev = f.item;
}
- if (prev) Delete(prev);
+ Delete(flist);
+ flist = newlist;
- if (has_all_prim) {
- String *func_call = NewStringf("(define-method (%s . args) (apply %s args))\n", clos_name, chickenPrimitiveName(scmname));
- if (construct)
- Printf(constructor_dispatch_func, "%s", func_call);
- else if (in_class)
- Printf(clos_class_methods, "%s", func_call);
- else
- Printf(closcode, "%s", func_call);
- Delete(func_call);
+ if (all_primitive) {
+ Printf(clos_methods, "(define %s %s)\n", method_name, chickenPrimitiveName(scmname));
+ } else {
+ for (f = First(flist); f.item; f = Next(f)) {
+ /* now export clos code for argument */
+ String *fmt = NewStringf("(define-method (%s %%s) %%s)\n", method_name);
+ String *func_call = buildClosFunctionCall(f.item, Char(fmt), chickenPrimitiveName(scmname), 1);
+ Printf(clos_methods, "%s", func_call);
+ Delete(f.item);
+ Delete(func_call);
+ }
+
+ if (has_empty_call) {
+ Printf(clos_methods, "(declare (hide %s))\n", method_name);
+ Printf(clos_methods, "(define (%s . args) (if (null? args) (%s) (apply %s@SWIG@multireal args)))\n",
+ clos_name, chickenPrimitiveName(scmname), clos_name);
+ }
}
+ Delete(method_name);
Delete(clos_name);
Delete(flist);
}