summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Examples/Makefile.in29
-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/Makefile29
-rw-r--r--Examples/fortran/simple/example.c17
-rw-r--r--Examples/fortran/simple/example.i7
-rw-r--r--Examples/fortran/simple/runme.f27
-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.swg86
-rw-r--r--Makefile.in2
-rw-r--r--Source/DOH/doh.h3
-rw-r--r--Source/DOH/string.c5
-rw-r--r--Source/Makefile.am1
-rw-r--r--Source/Modules/emit.cxx181
-rw-r--r--Source/Modules/fortran.cxx255
-rw-r--r--Source/Modules/swigmain.cxx2
-rw-r--r--Source/Modules/swigmod.h2
-rw-r--r--Source/Swig/parms.c19
-rw-r--r--Source/Swig/swigparm.h3
-rw-r--r--configure.in23
25 files changed, 850 insertions, 2 deletions
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index 32eaeccd9..9641103c4 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1142,6 +1142,35 @@ r_clean:
rm -f $(RRSRC) runme.Rout .RData
##################################################################
+##### FORTRAN ######
+##################################################################
+
+F77=@F77@
+CLIBPREFIX = lib
+#C_SO = @C_SO@
+#C_LDSHARED = @C_LDSHARED@
+#CXX_LDSHARED = @CXX_LDSHARED@
+
+
+fortran: $(SRCS)
+ $(SWIG) -fortran $(SWIGOPT) $(INTERFACEPATH)
+ $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS)
+ $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(CLIBPREFIX)$(TARGET)$(SO)
+
+fortran_cpp: $(SRCS)
+ $(SWIG) -c++ -fortran $(SWIGOPT) $(INTERFACEPATH)
+ $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES)
+ $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(CLIBPREFIX)$(TARGET)$(SO)
+
+fortran_compile: $(RUNME) $(PROXY)
+ $(F77) $(RUNME) $(PROXY) -L. -l$(TARGET) -o $(RUNME:.f=)
+
+fortran_clean:
+ rm -f *_wrap* *~ .~*
+ rm -f core @EXTRA_CLEAN@
+ rm -f *.@OBJEXT@ *@SO@
+
+##################################################################
##### Go ######
##################################################################
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
new file mode 100644
index 000000000..159300edb
--- /dev/null
+++ b/Examples/fortran/simple/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/simple/example.c b/Examples/fortran/simple/example.c
new file mode 100644
index 000000000..d81afc269
--- /dev/null
+++ b/Examples/fortran/simple/example.c
@@ -0,0 +1,17 @@
+/* File : example.c */
+#include <stdio.h>
+
+/* 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;
+}
diff --git a/Examples/fortran/simple/example.i b/Examples/fortran/simple/example.i
new file mode 100644
index 000000000..52b4dde83
--- /dev/null
+++ b/Examples/fortran/simple/example.i
@@ -0,0 +1,7 @@
+/* File : example.i */
+%module example
+
+%inline %{
+extern int gcd(int x, int y);
+//extern double Foo;
+%}
diff --git a/Examples/fortran/simple/runme.f b/Examples/fortran/simple/runme.f
new file mode 100644
index 000000000..fa25dcccb
--- /dev/null
+++ b/Examples/fortran/simple/runme.f
@@ -0,0 +1,27 @@
+! ----------------------------------------------------------------------
+! 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
+
+ a = 45
+ b = 105
+ g = 0
+
+ g = gcd(a, b)
+ write(*,*) "The gcd of ", a," and ", b, " is ", g
+
+! 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
new file mode 100644
index 000000000..b42daed0c
--- /dev/null
+++ b/Lib/fortran/fortran.swg
@@ -0,0 +1,86 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * fortran.swg
+ * ----------------------------------------------------------------------------- */
+
+%insert("runtime") %{
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+%}
+
+%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, 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 * {
+ Swig_fortranify($1, $input, $1_len);
+ free($1);
+}
+
+%insert(runtime) %{
+char* Swig_null_terminate(char* inStr, int len) {
+ int retVal = 0;
+ char* newStr = NULL;
+ char* current = NULL;
+
+ if (inStr && (len > 0) ) {
+
+ current = inStr+len-1;
+
+ while ((len > 0) && (isspace(*(current)))) {
+ // dont strip off newlines
+
+ if ( (*(current) == '\f')
+ || (*(current) == '\n')
+ || (*(current) == '\r')
+ || (*(current) == '\t')
+ || (*(current) == '\v') )
+ {
+ break;
+ }
+
+ if (--len) {
+ current--;
+ }
+ }
+
+ newStr = (char*) calloc(len+1,(sizeof(char)));
+ strncpy(newStr,inStr,len);
+ *(newStr+len) = '\0';
+
+ retVal++;
+ }
+
+ return newStr;
+}
+%}
+
+%insert(runtime) %{
+void Swig_fortranify(const char* inBuff, char* retText, int retTextLen) {
+
+ int inBuffLen = 0;
+ int i = 0;
+
+ if (inBuff && retText && (retTextLen > 0)) {
+ inBuffLen = strlen(inBuff);
+
+ strncpy(retText, inBuff, retTextLen);
+
+ // fortran-ify the string
+ if (inBuffLen < retTextLen) {
+ for (i = inBuffLen; i < retTextLen; i++) {
+ retText[i] = ' ';
+ }
+ }
+ }
+}
+%}
diff --git a/Makefile.in b/Makefile.in
index a12366e12..475e3b218 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -417,7 +417,7 @@ install-main:
@$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@
lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \
- pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d
+ pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d fortran
lib-modules = std
diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h
index bca5f0f0f..cfa6d79b2 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)
@@ -285,6 +286,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 */
@@ -421,6 +423,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 c326e9f40..ac770cea2 100644
--- a/Source/DOH/string.c
+++ b/Source/DOH/string.c
@@ -1131,6 +1131,7 @@ DOHString *DohNewStringf(const DOHString_or_char *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/Makefile.am b/Source/Makefile.am
index 984b9c268..0313dcade 100644
--- a/Source/Makefile.am
+++ b/Source/Makefile.am
@@ -45,6 +45,7 @@ eswig_SOURCES = CParse/cscanner.c \
Modules/d.cxx \
Modules/directors.cxx \
Modules/emit.cxx \
+ Modules/fortran.cxx \
Modules/go.cxx \
Modules/guile.cxx \
Modules/java.cxx \
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
new file mode 100644
index 000000000..ae43b6d56
--- /dev/null
+++ b/Source/Modules/fortran.cxx
@@ -0,0 +1,255 @@
+/* -----------------------------------------------------------------------------
+ * 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 {
+protected:
+ static const char *usage;
+
+ /* General DOH objects used for holding the strings */
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_proxyfxns;
+ File *f_init;
+
+
+public:
+
+ virtual void main(int argc, char *argv[]);
+
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+// virtual int variableWrapper(Node *n);
+
+};
+
+void FORTRAN::main(int argc, char *argv[]) {
+ printf("I'm the Fortran module.\n");
+ /* parse command line options
+ */
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stderr);
+ }
+ }
+ }
+
+ /* Set language-specific subdirectory in SWIG library */
+ SWIG_library_directory("fortran");
+
+ /* Set language-specific preprocessing symbol */
+ Preprocessor_define("SWIGFORTRAN 1", 0);
+
+ /* Set language-specific configuration file */
+ SWIG_config_file("fortran.swg");
+
+ /* Set typemap language (historical) */
+ SWIG_typemap_lang("fortran");
+
+}
+
+int FORTRAN::top(Node *n) {
+
+ printf("Generating code.\n");
+
+ /* Get the module name */
+ // String *module = Getattr(n,"name");
+
+ /* Get the output file name */
+ String *outfile = Getattr(n, "outfile");
+
+ /* Initialize I/O */
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_proxyfxns = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("proxyfxns", f_proxyfxns);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ /* Output module initialization code */
+ Swig_banner(f_begin);
+
+ /* Emit code for children */
+ Language::top(n);
+
+ /* Write all to the file */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Dump(f_proxyfxns, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ /* Cleanup files */
+ Delete(f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_proxyfxns);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_begin);
+
+ return SWIG_OK;
+}
+
+int FORTRAN::functionWrapper(Node *n) {
+ Printf(stdout, "creating function wrapper\n");
+ String *symname = Getattr(n, "sym:name");
+ String *type = Getattr(n, "type");
+
+ Wrapper *f = NewWrapper();
+ Wrapper *fproxy = NewWrapper();
+
+ ParmList *parms = Getattr(n, "parms");
+
+ // create new wrapper name
+ String *wname = Swig_name_wrapper(symname);
+ Setattr(n, "wrap:name", wname);
+
+ // create the function definition
+ String *return_type = SwigType_str(type, 0);
+
+ /* 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, "(", parmStr, ") {\n", NIL);
+
+ // create alternative call functions (proxyfxns)
+ // create proxy function with single underscore
+ 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 ");
+ }
+
+ Printv(fproxy->code, wname, "(", argsStr, ")", ";\n}", NIL);
+ Wrapper_print(fproxy, f_proxyfxns);
+
+ // create proxy function with double underscore
+ // create proxy function in all caps
+
+ // 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);
+
+ String *tm;
+ Parm *p;
+
+ /* Insert input typemap code */
+ 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 {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ String *outarg = NewString("");
+ p = parms;
+ while (p) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$1", Getattr(p, "lname"));
+ Replaceall(tm, "$input", Getattr(p, "name"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // attach local variables to parameters
+
+ // print input typemap conversions to wrapper.
+ Printv(f->code, inarg, "\n", NIL);
+ Delete(inarg);
+
+ if (!is_void_return) {
+ Printf(f->code, "result = ");
+ }
+
+ // 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);
+
+#if 0
+ Delete(symname);
+ Delete(type);
+ Delete(wname);
+ Delete(return_type);
+ Delete(parmStr);
+ Delete(argsStr);
+#endif
+
+ return SWIG_OK;
+}
+
+extern "C" Language *swig_fortran(void) {
+ return new FORTRAN();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+const char *FORTRAN::usage = (char *) "\
+\n";
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
index 01ab1b79f..bcccf7a1b 100644
--- a/Source/Modules/swigmain.cxx
+++ b/Source/Modules/swigmain.cxx
@@ -32,6 +32,7 @@ extern "C" {
Language *swig_python(void);
Language *swig_perl5(void);
Language *swig_ruby(void);
+ Language *swig_fortran(void);
Language *swig_guile(void);
Language *swig_modula3(void);
Language *swig_mzscheme(void);
@@ -72,6 +73,7 @@ static swig_module modules[] = {
{"-cffi", swig_cffi, "CFFI"},
{"-csharp", swig_csharp, "C#"},
{"-d", swig_d, "D"},
+ {"-fortran", swig_fortran, "FORTRAN"},
{"-go", swig_go, "Go"},
{"-guile", swig_guile, "Guile"},
{"-java", swig_java, "Java"},
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 208a7b026..142130628 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 *);
diff --git a/configure.in b/configure.in
index 052bf07c1..d84919861 100644
--- a/configure.in
+++ b/configure.in
@@ -1992,6 +1992,29 @@ fi
AC_SUBST(RBIN)
#----------------------------------------------------------------
+# Look for Fortran 77
+#----------------------------------------------------------------
+
+F77=
+
+AC_ARG_WITH(f77, AS_HELP_STRING([--without-f77], [Disable Fortran 77])
+AS_HELP_STRING([--with-f77=path], [Set location of Fortran 77 Compiler (f77)]),[ F77="$withval"], [F77=yes])
+
+# First, check for "--without-f77" or "--with-f77=no".
+if test x"${F77}" = xno -o x"${with_alllang}" = xno ; then
+AC_MSG_NOTICE([Disabling Fortran 77])
+F77=
+else
+
+# can we find F77?
+if test "x$F77" = xyes; then
+ AC_PATH_PROGS(F77, gfortran g77 f77)
+fi
+fi
+
+AC_SUBST(F77)
+
+#----------------------------------------------------------------
# Look for Go compilers
#----------------------------------------------------------------