summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerrick <a11426@users.sourceforge.net>2010-07-21 16:32:43 +0000
committerDerrick <a11426@users.sourceforge.net>2010-07-21 16:32:43 +0000
commit3e1af1f698d5d02d7905431bcb3549c0f7bc9aa7 (patch)
tree6c0c05fd1035a43fc6408785a6b039274caa525a
parentcf0008835580f07ca06529b74df0728cdb13a8fe (diff)
downloadswig-3e1af1f698d5d02d7905431bcb3549c0f7bc9aa7.tar.gz
Adding support for new typemap attributes extraparm and replaceparm. The
extraparm attribute is used in the fortran bindings to handle passing of fortran strings to C. When passing strings, fortran compilers add an additional parameter to the argument list representing the length of the string. The extraparms attribute can be added to a typemap, specifying the type and name of the extra parameter that should be added to wrapper function interfaces. The replaceparm attribute is used for passing integers, doubles, floats and other numeric values that fortran passes by address, but the c interface expects to receive by value. An example of this can be seen in the simple example. There are still a few problems with the new attributes. For example, once I get the typemap:in:extraparm attribute, I have a string with a type and variable name that represents the new extra parameter. The string may look like this: "size_t $1_len". If I want the name of the parameter, I have to manually parse it out of the string. The currently implementation, in the emit.cxx function named parse_name_from_arg, seems like a hack, but I think it will work. I would like to figure out if there is a way I can throw the string back through the swig parser and get let it parse the variable name from the type. Added the swig license header to fortran.cxx and incorporated the use of new typemap attributes extraparms and replaceparms to handle the currently supported datatypes during wrapper function generation. Added extraparm and replaceparm attributes to the fortran.swg. Updated namespace of the fortranify and null_terminate functions in fortran.swg. Separated out the string, simple, and array examples. Array example does not work yet. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/a11426-fortran@12165 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r--Examples/fortran/array/Makefile29
-rw-r--r--Examples/fortran/array/example.c23
-rw-r--r--Examples/fortran/array/example.i8
-rw-r--r--Examples/fortran/array/runme.f34
-rw-r--r--Examples/fortran/simple/Makefile2
-rw-r--r--Examples/fortran/simple/example.c7
-rw-r--r--Examples/fortran/simple/example.i1
-rw-r--r--Examples/fortran/simple/runme.f7
-rw-r--r--Examples/fortran/string/Makefile29
-rw-r--r--Examples/fortran/string/example.c9
-rw-r--r--Examples/fortran/string/example.i6
-rw-r--r--Examples/fortran/string/runme.f23
-rw-r--r--Lib/fortran/fortran.swg24
-rw-r--r--Source/DOH/doh.h3
-rw-r--r--Source/DOH/string.c5
-rw-r--r--Source/Modules/emit.cxx181
-rw-r--r--Source/Modules/fortran.cxx311
-rw-r--r--Source/Modules/swigmod.h2
-rw-r--r--Source/Swig/parms.c19
-rw-r--r--Source/Swig/swigparm.h3
20 files changed, 451 insertions, 275 deletions
diff --git a/Examples/fortran/array/Makefile b/Examples/fortran/array/Makefile
new file mode 100644
index 000000000..3643921d8
--- /dev/null
+++ b/Examples/fortran/array/Makefile
@@ -0,0 +1,29 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig -debug-module 4 > tree.txt
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+RUNME = runme.f
+PROXY =
+MEMTOOL = valgrind --leak-check=full
+
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' fortran
+ $(MAKE) -f $(TOP)/Makefile RUNME='$(RUNME)' PROXY='$(PROXY)' \
+ TARGET='$(TARGET)' fortran_compile
+
+run:
+ env LD_LIBRARY_PATH=. ./runme
+
+memchk:
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CFLAGS='-g' fortran
+ $(MAKE) -f $(TOP)/Makefile RUNME='$(RUNME)' PROXY='$(PROXY)' \
+ TARGET='$(TARGET)' CFLAGS='-g' fortran_compile
+ env LD_LIBRARY_PATH=. $(MEMTOOL) ./runme
+
+clean:
+ rm -f *.o *.so *.out *.a *.exe *.dll *.dylib *_wrap* *_proxy* *~ runme
+
+check: all
diff --git a/Examples/fortran/array/example.c b/Examples/fortran/array/example.c
new file mode 100644
index 000000000..d720509f2
--- /dev/null
+++ b/Examples/fortran/array/example.c
@@ -0,0 +1,23 @@
+/* File : example.c */
+#include <stdio.h>
+
+/* A global variable */
+double Foo = 3.0;
+
+/* Compute the greatest common divisor of positive integers */
+int* incrArrayInt(int *x, int nmemb) {
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+void sayhi(char *str, int y, char *ret) {
+ if (ret != NULL) {
+ sprintf(ret, "hello %s", str);
+ }
+ return;
+}
diff --git a/Examples/fortran/array/example.i b/Examples/fortran/array/example.i
new file mode 100644
index 000000000..bf55fab52
--- /dev/null
+++ b/Examples/fortran/array/example.i
@@ -0,0 +1,8 @@
+/* File : example.i */
+%module example
+
+%inline %{
+extern int gcd(int x, int y);
+extern void sayhi(char *x, int y, char *ret);
+//extern double Foo;
+%}
diff --git a/Examples/fortran/array/runme.f b/Examples/fortran/array/runme.f
new file mode 100644
index 000000000..5b89105b1
--- /dev/null
+++ b/Examples/fortran/array/runme.f
@@ -0,0 +1,34 @@
+! ----------------------------------------------------------------------
+! EXAMPLE: Calling a C function from fortran using swig.
+!
+! This simple example shows how to call a c funtion from Fortran
+!
+! ======================================================================
+! AUTHOR: Derrick Kearney, Purdue University
+! Copyright (c) 2005-2010 Purdue Research Foundation
+!
+! See the file "license.terms" for information on usage and
+! redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+! ======================================================================
+
+ program runme
+ IMPLICIT NONE
+
+ integer gcd, a, b , g
+
+ character*5 str
+ character*20 ret
+
+ a = 45
+ b = 105
+ g = 0
+
+ g = gcd(a, b)
+ write(*,*) "The gcd of ", a," and ", b, " is ", g
+
+ call sayhi(str, a, ret)
+ write(*,*) "The result of sayhi is ", ret
+
+
+! Swig_exit(0)
+ end program runme
diff --git a/Examples/fortran/simple/Makefile b/Examples/fortran/simple/Makefile
index 3643921d8..159300edb 100644
--- a/Examples/fortran/simple/Makefile
+++ b/Examples/fortran/simple/Makefile
@@ -1,5 +1,5 @@
TOP = ../..
-SWIG = $(TOP)/../preinst-swig -debug-module 4 > tree.txt
+SWIG = $(TOP)/../preinst-swig -debug-typemap -debug-module 4 > tree.txt
SRCS = example.c
TARGET = example
INTERFACE = example.i
diff --git a/Examples/fortran/simple/example.c b/Examples/fortran/simple/example.c
index 871c3819c..d81afc269 100644
--- a/Examples/fortran/simple/example.c
+++ b/Examples/fortran/simple/example.c
@@ -15,10 +15,3 @@ int gcd(int x, int y) {
}
return g;
}
-
-void sayhi(char *str, int y, char *ret) {
- if (ret != NULL) {
- sprintf(ret, "hello %s", str);
- }
- return;
-}
diff --git a/Examples/fortran/simple/example.i b/Examples/fortran/simple/example.i
index bf55fab52..52b4dde83 100644
--- a/Examples/fortran/simple/example.i
+++ b/Examples/fortran/simple/example.i
@@ -3,6 +3,5 @@
%inline %{
extern int gcd(int x, int y);
-extern void sayhi(char *x, int y, char *ret);
//extern double Foo;
%}
diff --git a/Examples/fortran/simple/runme.f b/Examples/fortran/simple/runme.f
index 5b89105b1..fa25dcccb 100644
--- a/Examples/fortran/simple/runme.f
+++ b/Examples/fortran/simple/runme.f
@@ -16,9 +16,6 @@
integer gcd, a, b , g
- character*5 str
- character*20 ret
-
a = 45
b = 105
g = 0
@@ -26,9 +23,5 @@
g = gcd(a, b)
write(*,*) "The gcd of ", a," and ", b, " is ", g
- call sayhi(str, a, ret)
- write(*,*) "The result of sayhi is ", ret
-
-
! Swig_exit(0)
end program runme
diff --git a/Examples/fortran/string/Makefile b/Examples/fortran/string/Makefile
new file mode 100644
index 000000000..159300edb
--- /dev/null
+++ b/Examples/fortran/string/Makefile
@@ -0,0 +1,29 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig -debug-typemap -debug-module 4 > tree.txt
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+RUNME = runme.f
+PROXY =
+MEMTOOL = valgrind --leak-check=full
+
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' fortran
+ $(MAKE) -f $(TOP)/Makefile RUNME='$(RUNME)' PROXY='$(PROXY)' \
+ TARGET='$(TARGET)' fortran_compile
+
+run:
+ env LD_LIBRARY_PATH=. ./runme
+
+memchk:
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CFLAGS='-g' fortran
+ $(MAKE) -f $(TOP)/Makefile RUNME='$(RUNME)' PROXY='$(PROXY)' \
+ TARGET='$(TARGET)' CFLAGS='-g' fortran_compile
+ env LD_LIBRARY_PATH=. $(MEMTOOL) ./runme
+
+clean:
+ rm -f *.o *.so *.out *.a *.exe *.dll *.dylib *_wrap* *_proxy* *~ runme
+
+check: all
diff --git a/Examples/fortran/string/example.c b/Examples/fortran/string/example.c
new file mode 100644
index 000000000..85d00b612
--- /dev/null
+++ b/Examples/fortran/string/example.c
@@ -0,0 +1,9 @@
+/* File : example.c */
+#include <stdio.h>
+
+void sayhi(char *str, char *ret) {
+ if (ret != NULL) {
+ sprintf(ret, "hello %s", str);
+ }
+ return;
+}
diff --git a/Examples/fortran/string/example.i b/Examples/fortran/string/example.i
new file mode 100644
index 000000000..f9a57c7be
--- /dev/null
+++ b/Examples/fortran/string/example.i
@@ -0,0 +1,6 @@
+/* File : example.i */
+%module example
+
+%inline %{
+extern void sayhi(char *x, char *ret);
+%}
diff --git a/Examples/fortran/string/runme.f b/Examples/fortran/string/runme.f
new file mode 100644
index 000000000..db73d78fe
--- /dev/null
+++ b/Examples/fortran/string/runme.f
@@ -0,0 +1,23 @@
+! ----------------------------------------------------------------------
+! EXAMPLE: Calling a C function from fortran using swig.
+!
+! The string example shows how to call a c funtion from Fortran
+!
+! ======================================================================
+
+ program runme
+ IMPLICIT NONE
+
+ character (LEN=7) :: name="derrick"
+ character*20 ret
+
+ call sayhi(name, ret)
+ write(*,*) "The result of sayhi is: ", ret
+
+! This case does not work
+! call sayhi("derrick", ret)
+! write(*,*) "The result of sayhi is: ", ret
+
+
+! Swig_exit(0)
+ end program runme
diff --git a/Lib/fortran/fortran.swg b/Lib/fortran/fortran.swg
index 305b42179..b42daed0c 100644
--- a/Lib/fortran/fortran.swg
+++ b/Lib/fortran/fortran.swg
@@ -5,33 +5,29 @@
* fortran.swg
* ----------------------------------------------------------------------------- */
-// WARNING: passing function pointers from C as parameters of type (or as
-// return values) SWIGTYPE (CLASS::*) causes cast of C function to type
-// void(*)() and it is user's responsibility to properly handle this
-// function's arguments and return value. See 'cpp_basic' test for details.
-
-//%insert("runtime") "clabels.swg"
-//%insert("proxy_header") "cproxy.swg"
-
%insert("runtime") %{
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
%}
-%typemap(in) int, float, double "$1 = *$input;"
+%typemap(in, replaceparm="$type *$input", noblock=1) int, float, double {
+ $1 = *$input;
+}
%typemap(in) char "$1 = $input;"
%typemap(in) int *, float *, double * "$1 = $input;"
-%typemap(in) char * "$1 = null_terminate($input, $length);"
+%typemap(in, extraparm="size_t $1_len", noblock=1) char * {
+ $1 = Swig_null_terminate($input, $1_len);
+}
// %typemap(argout) int, float, double "*$output = $input;"
%typemap(argout, noblock=1) char * {
- fortranify($input, $output, $length);
- free($input);
+ Swig_fortranify($1, $input, $1_len);
+ free($1);
}
%insert(runtime) %{
-char* null_terminate(char* inStr, int len) {
+char* Swig_null_terminate(char* inStr, int len) {
int retVal = 0;
char* newStr = NULL;
char* current = NULL;
@@ -69,7 +65,7 @@ char* null_terminate(char* inStr, int len) {
%}
%insert(runtime) %{
-void fortranify(const char* inBuff, char* retText, int retTextLen) {
+void Swig_fortranify(const char* inBuff, char* retText, int retTextLen) {
int inBuffLen = 0;
int i = 0;
diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h
index 1ed196058..bd692596d 100644
--- a/Source/DOH/doh.h
+++ b/Source/DOH/doh.h
@@ -99,6 +99,7 @@
#define DohStrncmp DOH_NAMESPACE(Strncmp)
#define DohStrstr DOH_NAMESPACE(Strstr)
#define DohStrchr DOH_NAMESPACE(Strchr)
+#define DohStrrchr DOH_NAMESPACE(Strrchr)
#define DohNewFile DOH_NAMESPACE(NewFile)
#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile)
#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd)
@@ -283,6 +284,7 @@ extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2);
extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n);
extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2);
extern char *DohStrchr(const DOHString_or_char *s1, int ch);
+extern char *DohStrrchr(const DOHString_or_char *s1, int ch);
/* String replacement flags */
@@ -419,6 +421,7 @@ extern void DohMemoryDebug(void);
#define Strncmp DohStrncmp
#define Strstr DohStrstr
#define Strchr DohStrchr
+#define Strrchr DohStrrchr
#define Copyto DohCopyto
#define Split DohSplit
#define SplitLines DohSplitLines
diff --git a/Source/DOH/string.c b/Source/DOH/string.c
index bd36c4094..276ae6b96 100644
--- a/Source/DOH/string.c
+++ b/Source/DOH/string.c
@@ -1131,6 +1131,7 @@ DOHString *DohNewStringf(const DOH *fmt, ...) {
* Strncmp()
* Strstr()
* Strchr()
+ * Strrchr()
*
* Some utility functions.
* ----------------------------------------------------------------------------- */
@@ -1158,3 +1159,7 @@ char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) {
char *DohStrchr(const DOHString_or_char *s1, int ch) {
return strchr(Char(s1), ch);
}
+
+char *DohStrrchr(const DOHString_or_char *s1, int ch) {
+ return strrchr(Char(s1), ch);
+}
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index 0c6c6515f..2a91ce2d6 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -14,6 +14,7 @@
char cvsroot_emit_cxx[] = "$Id$";
#include "swigmod.h"
+#include <ctype.h>
/* -----------------------------------------------------------------------------
* emit_return_variable()
@@ -98,6 +99,186 @@ void emit_parameter_variables(ParmList *l, Wrapper *f) {
}
/* -----------------------------------------------------------------------------
+ * apply_extraparm_attribute()
+ *
+ * returns tmap:in:extraparm attribute with variable replacements.
+ * ----------------------------------------------------------------------------- */
+
+String *apply_extraparm_attribute(Parm *p) {
+
+ String *s = Getattr(p,"tmap:in:extraparm");
+ if (s != NULL) {
+ Replaceall(s,"$1",Getattr(p, "lname"));
+ }
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * apply_replaceparm_attribute()
+ *
+ * returns tmap:in:replaceparm attribute variable replacements.
+ * ----------------------------------------------------------------------------- */
+
+String *apply_replaceparm_attribute(Parm *p) {
+
+ String *s = Getattr(p,"tmap:in:replaceparm");
+ if (s != NULL) {
+ Replaceall(s,"$type",Getattr(p, "type"));
+ Replaceall(s,"$input",Getattr(p, "name"));
+ }
+ return s;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * emit_parm_str()
+ *
+ * Returns a string of function parameter prototypes with extraparm attached.
+ * ----------------------------------------------------------------------------- */
+
+String *emit_parm_str(ParmList *p) {
+
+ String *s;
+ String *parmStr = NewStringEmpty();
+ String *extraParmStr = NewStringEmpty();
+ int pLen = 0;
+ int epLen = 0;
+
+ while (p) {
+ // check for extraparm attribute
+ s = apply_extraparm_attribute(p);
+
+ if (s != NULL) {
+ if (epLen > 0) {
+ Append(extraParmStr, ",");
+ }
+ Append(extraParmStr, s);
+ epLen++;
+ }
+
+ // check for replaceparm attribute
+ s = apply_replaceparm_attribute(p);
+ if (pLen > 0) {
+ Append(parmStr, ",");
+ }
+ String *o = NULL;
+ if (s == NULL) {
+ // if there was no parm replacement, use the original parm.
+ String *type = Getattr(p, "type");
+ o = SwigType_str(type ? type : NewStringEmpty(), Getattr(p, "name"));
+ s = o;
+ }
+ Append(parmStr, s);
+ if (o != NULL) {
+ Delete(o);
+ }
+ o = NULL;
+ pLen++;
+
+ p = nextSibling(p);
+ }
+
+ // add extra parameters at the end as necessary
+ if (epLen > 0) {
+ if (pLen > 0) {
+ Append(parmStr,",");
+ }
+ Append(parmStr,extraParmStr);
+ }
+
+ return parmStr;
+}
+
+/* -----------------------------------------------------------------------------
+ * parse_name_from_arg()
+ *
+ * given a string like "size_t s_len", return the variable name s_len.
+ * this function is used to parse strings from a typemaps with the
+ * extraparms="size_t $1_len" attribute
+ * ----------------------------------------------------------------------------- */
+
+char *parse_name_from_arg(String *arg) {
+ //FIXME: this is a bad way of parsing parameters from their types
+ // wish the text could be sent through the parser for correct parsing
+ char *s = NULL;
+
+ if (arg == NULL) {
+ return NULL;
+ }
+
+ s = Strrchr(arg,' ');
+ if (s != NULL) {
+ s++;
+ // lazy way of finding valid variable names
+ // valid variable names are a sequence of one or
+ // more letters, digits or underscore characters (_)
+ while (!isalnum(*s) && (*s != '_')) {
+ s++;
+ }
+ } else {
+ s = Char(arg);
+ }
+
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_args_str()
+ *
+ * Returns a string of function arguments with extraparm attached.
+ * ----------------------------------------------------------------------------- */
+
+String *emit_args_str(ParmList *p) {
+
+ String *s;
+ String *parmStr = NewStringEmpty();
+ String *extraParmStr = NewStringEmpty();
+ int pLen = 0;
+ int epLen = 0;
+ char *name = NULL;
+
+ while (p) {
+ // check for extraparm attribute
+ s = apply_extraparm_attribute(p);
+ if (s != NULL) {
+ if (epLen > 0) {
+ Append(extraParmStr, ",");
+ }
+ name = parse_name_from_arg(s);
+ Append(extraParmStr, name);
+ epLen++;
+ }
+
+ // check for replaceparm attribute
+ s = apply_replaceparm_attribute(p);
+ if (pLen > 0) {
+ Append(parmStr, ",");
+ }
+ if (s != NULL) {
+ name = parse_name_from_arg(s);
+ Append(parmStr, name);
+ } else {
+ // if there was no parm replacement, use the original parm.
+ s = Getattr(p, "name");
+ Append(parmStr, s);
+ }
+ pLen++;
+
+ p = nextSibling(p);
+ }
+
+ // add extra parameters at the end as necessary
+ if (epLen > 0) {
+ if (pLen > 0) {
+ Append(parmStr,",");
+ }
+ Append(parmStr,extraParmStr);
+ }
+
+ return parmStr;
+}
+
+/* -----------------------------------------------------------------------------
* emit_attach_parmmaps()
*
* Attach the standard parameter related typemaps.
diff --git a/Source/Modules/fortran.cxx b/Source/Modules/fortran.cxx
index 28f66b6f1..ae43b6d56 100644
--- a/Source/Modules/fortran.cxx
+++ b/Source/Modules/fortran.cxx
@@ -1,3 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * This file is part of SWIG, which is licensed as a whole under version 3-
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at http://www.swig.org/legal.html.
+ *
+ * fortran.cxx
+ *
+ * Fortran language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_fortran_cxx[] = "$Id:$";
+
+
#include "swigmod.h"
class FORTRAN:public Language {
@@ -104,161 +120,45 @@ int FORTRAN::top(Node *n) {
return SWIG_OK;
}
-Parm *getFirstParm(ParmList *p) {
- Parm *r = p;
- while (p) {
- p = previousSibling(p);
- if (p) {
- r = p;
- }
- }
- return r;
-}
-
-Parm *getLastParm(ParmList *p) {
- Parm *r = p;
- while (p) {
- p = nextSibling(p);
- if (p) {
- r = p;
- }
- }
- return r;
-}
-
-String *parmListAsString(ParmList *parm) {
- String *ret = NewString("");
- Parm *p = parm;
- while (p) {
- String *pstr = Getattr(p, "name");
- Append(ret, pstr);
- Delete(pstr);
- p = nextSibling(p);
- if (p) {
- Append(ret, ", ");
- }
- }
- return ret;
-}
-
-void protolenlisttostr(String *protolenstr, List *wargslenList) {
- int l = Len(wargslenList);
- int i = 0;
- if ((protolenstr == NULL) || (wargslenList == NULL)) {
- return;
- }
- while (i < l) {
- String *s = (String *) Getitem(wargslenList, i);
- Append(protolenstr, "int ");
- Append(protolenstr, s);
- i++;
- if (i < l) {
- Append(protolenstr, ", ");
- }
- }
-}
-
-void argslenlisttostr(String *protolenstr, List *wargslenList) {
- int l = Len(wargslenList);
- int i = 0;
- if ((protolenstr == NULL) || (wargslenList == NULL)) {
- return;
- }
- while (i < l) {
- String *s = (String *) Getitem(wargslenList, i);
- Append(protolenstr, s);
- i++;
- if (i < l) {
- Append(protolenstr, ", ");
- }
- }
-}
-
int FORTRAN::functionWrapper(Node *n) {
Printf(stdout, "creating function wrapper\n");
- String *name = Getattr(n, "sym:name");
+ String *symname = Getattr(n, "sym:name");
String *type = Getattr(n, "type");
- ParmList *parms = Getattr(n, "parms");
Wrapper *f = NewWrapper();
Wrapper *fproxy = NewWrapper();
+ ParmList *parms = Getattr(n, "parms");
+
// create new wrapper name
- String *wname = Swig_name_wrapper(name);
+ String *wname = Swig_name_wrapper(symname);
Setattr(n, "wrap:name", wname);
// create the function definition
String *return_type = SwigType_str(type, 0);
- String *wproto = NewString("");
-// String *wargs = NewString("");
-// String *protoLen = NewString("");
-// String *protoLens = NewString("");
- ParmList *wparms = CopyParmList(parms);
- Parm *p = wparms;
-// List *wprotoList = NewList();
- List *wargslenList = NewList();
- while (p) {
- String *ptype = Getattr(p, "type");
- String *ptypeResolved = SwigType_typedef_resolve_all(ptype);
- if (Strcmp(SwigType_str(ptypeResolved, 0), "char *") == 0) {
- // if argument resolves to a character array,
- // we need an additional parameter to describe
- // the size of the array
- String *npName = NewString("");
- Printv(npName, Getattr(p, "name"), "_len", NIL);
- Insert(wargslenList, DOH_END, npName);
- Delete(npName);
- } else if ((Strcmp(SwigType_str(ptypeResolved, 0), "int") == 0) ||
- (Strcmp(SwigType_str(ptypeResolved, 0), "short") == 0) ||
- (Strcmp(SwigType_str(ptypeResolved, 0), "float") == 0) ||
- (Strcmp(SwigType_str(ptypeResolved, 0), "double") == 0) ||
- (Strcmp(SwigType_str(ptypeResolved, 0), "long") == 0)) {
- // fortran sends the address of integers
- SwigType_add_pointer(ptype);
- Setattr(p, "type", ptype);
- }
- String *pstr = SwigType_str(ptype, Getattr(p, "name"));
- Append(wproto, pstr);
- p = nextSibling(p);
- if (p) {
- Append(wproto, ", ");
- }
- Delete(pstr);
- Delete(ptype);
- Delete(ptypeResolved);
- }
- if (Len(wargslenList) > 0) {
- String *s = NewString("");
- protolenlisttostr(s, wargslenList);
- Append(wproto, ", ");
- Append(wproto, s);
- Delete(s);
- }
- // argslenlisttostr(argslenstr, wargslenList);
+ /* Attach standard typemaps */
+ emit_attach_parmmaps(parms, f);
+ Setattr(n, "wrap:parms", parms);
+
+ /* Generate prototype and parameter strings
+ with extra parameters attached. extra parameters
+ are not sent through the typemap system. */
+ String *parmStr = emit_parm_str(parms);
+ String *argsStr = emit_args_str(parms);
- Printv(f->def, return_type, " ", wname, "(", wproto, ") {\n", NIL);
+ Printv(f->def, return_type, " ", wname, "(", parmStr, ") {\n", NIL);
// create alternative call functions (proxyfxns)
// create proxy function with single underscore
- // p = getFirstParm(lastParm);
- Printv(fproxy->def, return_type, " ", name, "_", "(", wproto, ") {\n", NIL);
+ Printv(fproxy->def, return_type, " ", symname, "_", "(", parmStr, ") {\n", NIL);
+
bool is_void_return = (SwigType_type(type) == T_VOID);
if (!is_void_return) {
Printf(fproxy->code, "return ");
}
- // String *wrapFxnCall = Swig_cfunction_call(wname, wparms);
- // Printv(fproxy->code, wrapFxnCall, ";\n}", NIL);
- String *wargs = parmListAsString(wparms);
- if (Len(wargslenList) > 0) {
- String *s = NewString("");
- argslenlisttostr(s, wargslenList);
- Append(wargs, ", ");
- Append(wargs, s);
- Delete(s);
- }
- Printv(fproxy->code, wname, "(", wargs, ")", ";\n}", NIL);
- Delete(wargs);
+
+ Printv(fproxy->code, wname, "(", argsStr, ")", ";\n}", NIL);
Wrapper_print(fproxy, f_proxyfxns);
// create proxy function with double underscore
@@ -267,112 +167,36 @@ int FORTRAN::functionWrapper(Node *n) {
// Emit all of the local variables for holding arguments.
emit_parameter_variables(parms, f);
+
// Emit variable holding return value.
emit_return_variable(n, return_type, f);
-
- /* Attach standard typemaps */
- emit_attach_parmmaps(parms, f);
- Setattr(n, "wrap:parms", parms);
-
- /* Get number of require and total arguments */
- int num_arguments = emit_num_arguments(parms);
-
- /* Unmarshal parameters */
- String *source;
- String *source_len;
String *tm;
- String *incode = NewString("");
- // ParmList *p2 = NULL;
- Parm *p2;
- int i = 0;
+ Parm *p;
/* Insert input typemap code */
- for (i = 0, p2 = parms; i < num_arguments; i++) {
- /* Skip ignored arguments */
-
- while (checkAttribute(p2, "tmap:in:numinputs", "0")) {
- p2 = Getattr(p2, "tmap:in:next");
- }
-
- SwigType *pt = Getattr(p2, "type");
- String *ln = Getattr(p2, "lname");
-
-
- if ((tm = Getattr(p2, "tmap:in"))) {
- String *parse = Getattr(p2, "tmap:in:parse");
- if (!parse) {
- /* Produce string representations of the source and target arguments */
- source = Getattr(p2, "name");
- source_len = NewString("");
- Printv(source_len, Getattr(p2, "name"), "_len", NIL);
-
- Replaceall(tm, "$target", ln);
- Replaceall(tm, "$source", source);
- Replaceall(tm, "$input", source);
- Replaceall(tm, "$length", source_len);
- Setattr(p2, "emit:input", source);
-
- Printf(incode, "%s\n", tm);
- Delete(source_len);
- } else {
- printf("tmap:in:parse was null\n");
- }
- p2 = Getattr(p2, "tmap:in:next");
- continue;
+ String *inarg = NewString("");
+ p = parms;
+ while (p) {
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$1", Getattr(p, "lname"));
+ Replaceall(tm, "$input", Getattr(p, "name"));
+ Printv(inarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:in:next");
} else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ p = nextSibling(p);
}
- p2 = nextSibling(p);
}
- // print input typemap conversions to wrapper.
- Printv(f->code, incode, "\n", NIL);
-
- /* Insert constraint checking code */
-/*
- for (p = parms; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Replaceall(tm, "$target", Getattr(p, "lname"));
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
-*/
-
- /* Insert cleanup code */
-/*
- for (i = 0, p = parms; p; i++) {
- if (!checkAttribute(p, "tmap:in:numinputs", "0")
- && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
- if (Len(tm) != 0) {
- Replaceall(tm, "$source", Getattr(p, "lname"));
- Printv(cleanup, tm, "\n", NIL);
- }
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
-*/
-
/* Insert argument output code */
String *outarg = NewString("");
- for (i = 0, p = parms; p; i++) {
+ p = parms;
+ while (p) {
if ((tm = Getattr(p, "tmap:argout"))) {
-
- source = Getattr(p, "name");
- source_len = NewString("");
- Printv(source_len, Getattr(p, "name"), "_len", NIL);
-
- Replaceall(tm, "$input", Getattr(p, "lname"));
- Replaceall(tm, "$output", source);
- Replaceall(tm, "$length", source_len);
+ Replaceall(tm, "$1", Getattr(p, "lname"));
+ Replaceall(tm, "$input", Getattr(p, "name"));
Printv(outarg, tm, "\n", NIL);
p = Getattr(p, "tmap:argout:next");
- Delete(source_len);
} else {
p = nextSibling(p);
}
@@ -380,41 +204,41 @@ int FORTRAN::functionWrapper(Node *n) {
// attach local variables to parameters
- // create function call
- // get function definition arguments
- String *empty_string = NewString("");
- String *arg_names = Swig_cfunction_call(empty_string, parms);
- if (arg_names) {
- // remove parenthesis before and after argument list
- Delitem(arg_names, 0);
- Delitem(arg_names, DOH_END);
- }
+ // print input typemap conversions to wrapper.
+ Printv(f->code, inarg, "\n", NIL);
+ Delete(inarg);
if (!is_void_return) {
Printf(f->code, "result = ");
}
- Printv(f->code, name, "(", arg_names, ");\n", NIL);
+
+ // create function call
+ // get function definition arguments
+ String *empty_string = NewString("");
+ String *arg_names = Swig_cfunction_call(empty_string, parms);
+ Printv(f->code, symname, arg_names, ";\n", NIL);
+ Delete(empty_string);
+ Delete(arg_names);
// attach output arguments
Printv(f->code, "\n", outarg, "\n", NIL);
+ Delete(outarg);
if (!is_void_return) {
Printf(f->code, "return result;\n");
}
Printf(f->code, "}");
-
// write out the wrapper file
Wrapper_print(f, f_wrappers);
- Delete(name);
-// Delete(type);
+#if 0
+ Delete(symname);
+ Delete(type);
Delete(wname);
- Delete(arg_names);
Delete(return_type);
-// Delete(proto);
- Delete(empty_string);
- Delete(incode);
- Delete(outarg);
+ Delete(parmStr);
+ Delete(argsStr);
+#endif
return SWIG_OK;
}
@@ -428,5 +252,4 @@ extern "C" Language *swig_fortran(void) {
* ----------------------------------------------------------------------------- */
const char *FORTRAN::usage = (char *) "\
-C Options (available with -c)\n\
\n";
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index b0b488d6f..693a67071 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -336,6 +336,8 @@ void SWIG_library_directory(const char *);
int emit_num_arguments(ParmList *);
int emit_num_required(ParmList *);
int emit_isvarargs(ParmList *);
+String *emit_parm_str(ParmList *p);
+String *emit_args_str(ParmList *p);
void emit_attach_parmmaps(ParmList *, Wrapper *f);
void emit_mark_varargs(ParmList *l);
String *emit_action(Node *n);
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index 283a2f5c2..4e0a0554a 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -227,6 +227,25 @@ String *ParmList_protostr(ParmList *p) {
}
/* ---------------------------------------------------------------------
+ * ParmList_argsstr()
+ *
+ * Generate a arguments string.
+ * ---------------------------------------------------------------------- */
+
+String *ParmList_argsstr(ParmList *p) {
+ String *out = NewStringEmpty();
+ while (p) {
+ String *name = Getattr(p, "name");
+ Append(out, name);
+ p = nextSibling(p);
+ if (p) {
+ Append(out, ",");
+ }
+ }
+ return out;
+}
+
+/* ---------------------------------------------------------------------
* ParmList_has_defaultargs()
*
* Returns 1 if the parameter list passed in is has one or more default
diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h
index 70a39390e..51a3dacfa 100644
--- a/Source/Swig/swigparm.h
+++ b/Source/Swig/swigparm.h
@@ -9,7 +9,7 @@
* swigparm.h
*
* Functions related to the handling of function/method parameters and
- * parameter lists.
+ * parameter lists.
* ----------------------------------------------------------------------------- */
/* Individual parameters */
@@ -29,5 +29,6 @@ extern String *ParmList_str(ParmList *);
extern String *ParmList_str_defaultargs(ParmList *);
extern String *ParmList_str_multibrackets(ParmList *);
extern String *ParmList_protostr(ParmList *);
+extern String *ParmList_argsstr(ParmList *);