summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorallen <allen@17b73243-c579-4c4c-a9d2-2d5706c11dac>2001-02-24 17:31:09 +0000
committerallen <allen@17b73243-c579-4c4c-a9d2-2d5706c11dac>2001-02-24 17:31:09 +0000
commit1b62c7f62e4e80831abec3e615ed66d1d5a02219 (patch)
treea2d9577722af159a7de1e759875ea47facd08fe8
parent3042fe913f3928e9e561e75d4c63c93baa7c9390 (diff)
Initial implementation of Function Aliasing for thorns.
This is described on a Spec on the web pages at the moment, and will move to the documentation once it is tested and extended a bit more. If you want to have a look at it in action, checkout the thorns TestFunctions1A, TestFunctions1B and TestFunctions2 which will be in AlphaThorns in a few minutes time. At the moment it is only possible to use Function Aliasing for C functions which use and return Cactus data types. You will need to rebuild your configurations once you update, but apart from that these changes shouldn't affect anyone ... if you see any problems please let us know. Gabrielle git-svn-id: http://svn.cactuscode.org/flesh/trunk@2060 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--lib/make/make.config.defn.in2
-rw-r--r--lib/sbin/CST7
-rw-r--r--lib/sbin/CreateFunctionBindings.pl716
-rw-r--r--lib/sbin/interface_parser.pl126
-rw-r--r--src/include/cctk.h1
-rw-r--r--src/main/InitialiseCactus.c2
-rw-r--r--src/main/Subsystems.c4
7 files changed, 723 insertions, 135 deletions
diff --git a/lib/make/make.config.defn.in b/lib/make/make.config.defn.in
index 879dc531..5bf88e1f 100644
--- a/lib/make/make.config.defn.in
+++ b/lib/make/make.config.defn.in
@@ -111,7 +111,7 @@ F90_POSTPROCESSING = @F90_POSTPROCESSING@
# Exclude some files from the dependency lists
-DEP_EXCLUDE_FILES = CParameterStructNames\.h|cctk_Arguments\.h|definethisthorn\.h|FParameters.h|CParameters\.h
+DEP_EXCLUDE_FILES = cctk_FunctionAliases\.h|CParameterStructNames\.h|cctk_Arguments\.h|definethisthorn\.h|FParameters.h|CParameters\.h
# Command used to get the working directory
GET_WD = @GET_WD@
diff --git a/lib/sbin/CST b/lib/sbin/CST
index e18e0617..bbff1bb6 100644
--- a/lib/sbin/CST
+++ b/lib/sbin/CST
@@ -6,7 +6,7 @@
# @desc
# Parses the the configuration files for thorns.
# @enddesc
-# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.39 2000-09-17 09:45:45 allen Exp $
+# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.40 2001-02-24 17:31:08 allen Exp $
#@@*/
# Global parameter to track the number of errors from the CST
@@ -76,6 +76,7 @@ require "$sbin_dir/CSTUtils.pl";
require "$sbin_dir/CreateParameterBindings.pl";
require "$sbin_dir/CreateImplementationBindings.pl";
require "$sbin_dir/CreateScheduleBindings.pl";
+require "$sbin_dir/CreateFunctionBindings.pl";
require "$sbin_dir/BuildHeaders.pl";
#######################################################################
@@ -538,12 +539,14 @@ sub CreateBindings
&CreateVariableBindings($bindings_dir, $rhinterface_db);
print " Creating schedule bindings...\n";
&CreateScheduleBindings($bindings_dir, $rhinterface_db, $rhschedule_db);
+ print " Creating function bindings...\n";
+ &CreateFunctionBindings($bindings_dir, $rhinterface_db);
# Place an appropriate make.code.defn in the bindings directory.
chdir $bindings_dir;
$dataout = "SRCS = \n";
- $dataout .= "SUBDIRS = Implementations Parameters Variables Schedule\n";
+ $dataout .= "SUBDIRS = Functions Implementations Parameters Variables Schedule\n";
&WriteFile("make.code.defn",\$dataout);
# Go back to where we started.
diff --git a/lib/sbin/CreateFunctionBindings.pl b/lib/sbin/CreateFunctionBindings.pl
index 84906001..da2bbc94 100644
--- a/lib/sbin/CreateFunctionBindings.pl
+++ b/lib/sbin/CreateFunctionBindings.pl
@@ -2,7 +2,7 @@
#/*@@
# @file CreateFunctionBindings.pl
# @date Sat Feb 10 2001
-# @author Tom Goodale
+# @author Gabrielle Allen
# @desc
#
# @enddesc
@@ -66,12 +66,35 @@ sub CreateFunctionBindings
&WriteFile("DummyThornFunctions.c",\$dataout);
chdir $bindings_dir;
+# Create OverloadThorns.c
+ chdir "Functions";
+ $dataout = &OverloadThorns();
+ &WriteFile("OverloadThorns.c",\$dataout);
+ chdir $bindings_dir;
+
# Create FortranThornFunctions.c
chdir "Functions";
$dataout = &FortranThornFunctions($function_db);
&WriteFile("FortranThornFunctions.c",\$dataout);
chdir $bindings_dir;
+# Create Thorn Include Prototypes
+ chdir "include";
+ foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
+ {
+ $filename = $thorn."_Prototypes.h";
+ $dataout = &ThornIncludes($thorn,$function_db,$rhinterface_db);
+ &WriteFile($filename,\$dataout);
+ }
+ chdir $bindings_dir;
+
+# Create Master Include Prototypes
+ chdir "include";
+ $filename = "cctk_FunctionAliases.h";
+ $dataout = &ThornMasterIncludes($rhinterface_db);
+ &WriteFile($filename,\$dataout);
+ chdir $bindings_dir;
+
# Create THORN_Register.c
chdir "Functions";
$registerfiles = "";
@@ -90,11 +113,15 @@ sub CreateFunctionBindings
&WriteFile("RegisterThornFunctions.c",\$dataout);
chdir $bindings_dir;
-
+# Create IsOverloaded functions
+ chdir "Functions";
+ $dataout = &IsOverloadedBindings($function_db);
+ &WriteFile("IsOverloaded.c",\$dataout);
+ chdir $bindings_dir;
# Create make.code.defn
chdir "Functions";
- $dataout = "\nSRCS = FortranThornFunctions.c DummyThornFunctions.c RegisterThornFunctions.c $registerfiles\n\n";
+ $dataout = "\nSRCS = IsOverloaded.c OverloadThorns.c FortranThornFunctions.c DummyThornFunctions.c RegisterThornFunctions.c $registerfiles\n\n";
&WriteFile("make.code.defn",\$dataout);
chdir $start_dir;
@@ -103,6 +130,119 @@ sub CreateFunctionBindings
#/*@@
+# @routine IsOverloadedBindings
+# @date Tue Feb 20 2001
+# @author Gabrielle Allen
+# @desc
+# Code for returning number of times a function has been overloaded.
+# This should be done in a better way, and include flesh overloaded
+# functions
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+
+sub IsOverloadedBindings
+{
+ my($function_db) = @_;
+ my($dataout,$line,@data);
+
+ # Header Data
+ $line = "/*\@\@\n";
+ push(@data, $line);
+ $line = " \@header IsOverloaded.c\n";
+ push(@data, $line);
+ $line = " \@desc\n";
+ push(@data, $line);
+ $line = " Query how many times a function is overloaded\n";
+ push(@data, $line);
+ $line = " \@enddesc \n";
+ push(@data, $line);
+ $line = " \@\@*/\n\n";
+ push(@data, $line);
+
+ $line = "\#include <stdlib.h>\n\n";
+ push(@data, $line);
+ $line = "\#include \"cctk_Flesh.h\"\n\n";
+ push(@data, $line);
+ $line = "\#include \"cctk_FortranString.h\"\n\n";
+ push(@data, $line);
+
+ foreach $function (split(" ",$function_db->{"FUNCTIONS"}))
+ {
+ if ($function !~ m:^\s*$:)
+ {
+ $line = "int CCTKBindings_Overload$function(void *);\n";
+ push(@data, $line);
+ }
+ }
+
+ $line = "int CCTK_IsOverloaded(const char *function);\n";
+ push(@data, $line);
+
+ $line = "int CCTK_IsOverloaded(const char *function)\n";
+ push(@data, $line);
+ $line = "{\n";
+ push(@data, $line);
+ $line = " int retval=0;\n\n";
+ push(@data, $line);
+
+ foreach $function (split(" ",$function_db->{"FUNCTIONS"}))
+ {
+ if ($function !~ m:^\s*$:)
+ {
+ $line = " if (strcmp(function,\"$function\")==0)\n";
+ push(@data, $line);
+ $line = " {\n";
+ push(@data, $line);
+ $line = " retval = CCTKBindings_Overload$function(NULL);\n";
+ push(@data, $line);
+ $line = " }\n\n";
+ push(@data, $line);
+ }
+ }
+
+ $line = " return retval;\n";
+ push(@data, $line);
+ $line = "}\n\n\n";
+ push(@data, $line);
+
+ # Put fortran binding here for the moment
+ $line = "void CCTK_FCALL CCTK_FNAME(CCTK_IsOverloaded)\n";
+ push(@data, $line);
+ $line = " (int *ret, ONE_FORTSTRING_ARG);\n";
+ push(@data, $line);
+ $line = "void CCTK_FCALL CCTK_FNAME(CCTK_IsOverloaded)\n";
+ push(@data, $line);
+ $line = " (int *ret, ONE_FORTSTRING_ARG)\n";
+ push(@data, $line);
+ $line = "{\n";
+ push(@data, $line);
+ $line = " ONE_FORTSTRING_CREATE(name);\n";
+ push(@data, $line);
+ $line = " *ret = CCTK_IsOverloaded(name);\n";
+ push(@data, $line);
+ $line = " free(name);\n";
+ push(@data, $line);
+ $line = "}\n";
+ push(@data, $line);
+
+
+ $dataout = "";
+ foreach $line (@data)
+ {
+ $dataout .= $line;
+ }
+
+ return $dataout;
+}
+
+
+#/*@@
# @routine ThornOverloadables
# @date Sat Feb 10
# @author Gabrielle Allen
@@ -220,6 +360,255 @@ sub ThornOverloadables
}
+
+#/*@@
+# @routine ThornMasterIncludes
+# @date Thu Feb 15 2001
+# @author Gabrielle Allen
+# @desc
+# Master file of function prototypes for each thorn
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+
+sub ThornMasterIncludes
+{
+ my($rhinterface_db) = @_;
+ my($line,@data,$dataout,$thorn);
+
+ # Header Data
+ $line = "/*\@\@\n";
+ push(@data, $line);
+ $line = " \@header cctk_FunctionAliases.h\n";
+ push(@data, $line);
+ $line = " \@desc\n";
+ push(@data, $line);
+ $line = " Prototypes for overloaded functions used by all thorn\n";
+ push(@data, $line);
+ $line = " \@enddesc \n";
+ push(@data, $line);
+ $line = " \@\@*/\n\n";
+ push(@data, $line);
+ $line = "\#ifndef _CCTK_FUNCTIONALIASES_H_\n";
+ push(@data, $line);
+ $line = "\#define _CCTK_FUNCTIONALIASES_H_\n\n";
+ push(@data, $line);
+
+ $line = "\#ifdef CCODE\n";
+ push(@data, $line);
+ $line = "int CCTK_IsOverloaded(const char *function);\n\n";
+ push(@data, $line);
+ $line = "\#endif\n\n";
+ push(@data, $line);
+
+ foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
+ {
+ $line = "\#ifdef THORN_IS_$thorn\n";
+ push(@data, $line);
+ $line = "\#include \"$thorn"."_Prototypes.h\"\n";
+ push(@data, $line);
+ $line = "\#endif\n\n";
+ push(@data, $line);
+ }
+
+ $line = "\#endif\n\n";
+ push(@data, $line);
+
+ $dataout = "";
+ foreach $line (@data)
+ {
+ $dataout .= $line;
+ }
+
+ return $dataout;
+}
+
+
+
+#/*@@
+# @routine OverloadThorns
+# @date Tue Feb 20 2001
+# @author Gabrielle Allen
+# @desc
+# Main file for overloading thorns. Note that the text doesn't change
+# but the contents does depending on the thorn set used. For this reason
+# it is in the bindings and not in the Flesh.
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+
+sub OverloadThorns
+{
+ my($line,@data,$dataout);
+
+ # Header Data
+ $line = "/*\@\@\n";
+ push(@data, $line);
+ $line = "\@file OverloadThornFunctions.c\n";
+ push(@data, $line);
+ $line = "\@desc \n";
+ push(@data, $line);
+ $line = "Contains routines to overload thorn functions\n";
+ push(@data, $line);
+ $line = "Uses the overload macros to make sure of consistency and\n";
+ push(@data, $line);
+ $line = "to save typing !\n";
+ push(@data, $line);
+ $line = "\@enddesc\n";
+ push(@data, $line);
+ $line = "\@\@*/\n\n";
+ push(@data, $line);
+
+ $line = "\#include <stdio.h>\n";
+ push(@data, $line);
+ $line = "\#include <stdlib.h>\n";
+ push(@data, $line);
+ $line = "\#include <string.h>\n\n";
+ push(@data, $line);
+
+ $line = "\#include \"cctk_Flesh.h\"\n";
+ push(@data, $line);
+ $line = "\#include \"cctk_WarnLevel.h\"\n";
+ push(@data, $line);
+ $line = "\#include \"OverloadMacros.h\"\n\n";
+ push(@data, $line);
+
+ $line = "/* Define the prototypes for the dummy functions. */\n";
+ push(@data, $line);
+ $line = "\#define OVERLOADABLE(name) OVERLOADABLE_DUMMYPROTOTYPE(name)\n\n";
+ push(@data, $line);
+
+ $line = "\#include \"ThornOverloadables.h\"\n\n";
+ push(@data, $line);
+
+ $line = "\#undef OVERLOADABLE\n\n";
+ push(@data, $line);
+
+ $line = "\#define OVERLOADABLE(name) OVERLOADABLE_FUNCTION(name)\n\n";
+ push(@data, $line);
+
+ $line = "\#include \"ThornOverloadables.h\"\n\n";
+ push(@data, $line);
+
+ $line = "\#undef OVERLOADABLE\n\n";
+ push(@data, $line);
+
+ $line = "\#undef OVERLOADABLE_CALL\n";
+ push(@data, $line);
+ $line = "\#undef OVERLOADABLE_PREFIX\n";
+ push(@data, $line);
+ $line = "\#undef OVERLOADABLE_DUMMY_PREFIX\n\n";
+ push(@data, $line);
+
+ $line = "/* Initialising Stuff */\n\n";
+ push(@data, $line);
+
+ $line = "void CCTKBindings_SetupThornFunctions(void);\n";
+ push(@data, $line);
+ $line = "void CCTKBindings_SetupThornFunctions(void)\n";
+ push(@data, $line);
+ $line = "{\n";
+ push(@data, $line);
+ $line = "\#undef OVERLOADABLE\n";
+ push(@data, $line);
+ $line = "\#define OVERLOADABLE(name) OVERLOADABLE_INITIALISE(name)\n";
+ push(@data, $line);
+ $line = "\#include \"ThornOverloadables.h\"\n";
+ push(@data, $line);
+ $line = "#undef OVERLOADABLE\n";
+ push(@data, $line);
+ $line = "}\n\n";
+ push(@data, $line);
+
+ $dataout = "";
+ foreach $line (@data)
+ {
+ $dataout .= $line;
+ }
+
+ return $dataout;
+}
+
+
+
+#/*@@
+# @routine ThornIncludes.h
+# @date Thu Feb 15 2001
+# @author Gabrielle Allen
+# @desc
+# Create function prototypes for each thorn
+# @enddesc
+# @calls
+# @calledby
+# @history
+#
+# @endhistory
+#
+#@@*/
+
+sub ThornIncludes
+{
+
+ my($thorn,$function_db,$rhinterface_db) = @_;
+ my($line,@data,$dataout,$function);
+
+ # Header Data
+ $line = "/*\@\@\n";
+ push(@data, $line);
+ $line = " \@header $thorn"."_Prototypes.h\n";
+ push(@data, $line);
+ $line = " \@desc\n";
+ push(@data, $line);
+ $line = " Prototypes for overloaded functions used by this thorn\n";
+ push(@data, $line);
+ $line = " \@enddesc \n";
+ push(@data, $line);
+ $line = " \@\@*/\n\n";
+ push(@data, $line);
+ $line = "\#ifndef _\U$thorn\E_PROTOTYPES_H_\n";
+ push(@data, $line);
+ $line = "\#define _\U$thorn\E_PROTOTYPES_H_\n\n";
+ push(@data, $line);
+
+
+ $line = "\#ifdef CCODE\n";
+ push(@data, $line);
+
+ foreach $function (split(" ",($rhinterface_db->{"\U$thorn USES FUNCTION\E"})))
+ {
+ if ($function !~ m:^\s*$:)
+ {
+ $line = "extern $function_db->{\"$function RET\"} (*$function)($function_db->{\"$function CARGS\"});\n";
+ push(@data, $line);
+ }
+ }
+
+ $line = "\#endif /*CCODE*/\n\n";
+ push(@data, $line);
+
+ $line = "\#endif\n\n";
+ push(@data, $line);
+
+ $dataout = "";
+ foreach $line (@data)
+ {
+ $dataout .= $line;
+ }
+
+ return $dataout;
+}
+
+
#/*@@
# @routine RegisterAllFunctions
# @date Sun Feb 11 2001
@@ -250,6 +639,14 @@ sub RegisterAllFunctions
push(@data, $line);
$line = " \@enddesc \n";
push(@data, $line);
+ $line = " \@returntype int\n";
+ push(@data, $line);
+ $line = " \@returndesc \n";
+ push(@data, $line);
+ $line = " Minus number of failed overloads\n";
+ push(@data, $line);
+ $line = " \@endreturndesc\n";
+ push(@data, $line);
$line = " \@\@*/\n\n";
push(@data, $line);
$line = "\#include \"cctk_Flesh.h\"\n";
@@ -259,27 +656,30 @@ sub RegisterAllFunctions
foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
{
- $line = "int ".$thorn."_RegisterAliases(void);\n";
+ $line = "int CCTKBindings_".$thorn."Aliases(void);\n";
push(@data, $line);
}
- $line = "int CCTKi_BindingsRegisterThornFunctions(void);\n\n";
+ $line = "int CCTKBindings_RegisterThornFunctions(void);\n\n";
push(@data, $line);
- $line = "int CCTKi_BindingsRegisterThornFunctions(void)\n";
+ $line = "int CCTKBindings_RegisterThornFunctions(void)\n";
push(@data, $line);
$line = "{\n";
push(@data, $line);
+ $line = " int retval = 0;\n";
+ push(@data, $line);
+
foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
{
$line = " if (CCTK_IsThornActive(\"$thorn\"))\n";
push(@data, $line);
$line = " {\n";
push(@data, $line);
- $line = " $thorn"."_RegisterAliases();\n";
+ $line = " retval =+ CCTKBindings_".$thorn."Aliases();\n";
push(@data, $line);
$line = " }\n";
push(@data, $line);
}
- $line = " return 0;\n";
+ $line = " return retval;\n";
push(@data, $line);
$line = "}\n";
push(@data, $line);
@@ -327,6 +727,8 @@ sub DummyThornFunctions
push(@data, $line);
$line = " \@\@*/\n\n";
push(@data, $line);
+ $line = "\#include <stdlib.h>\n\n";
+ push(@data, $line);
$line = "\#include \"cctk_Flesh.h\"\n";
push(@data, $line);
$line = "\#include \"cctk_WarnLevel.h\"\n\n";
@@ -336,14 +738,69 @@ sub DummyThornFunctions
{
if ($function !~ m:^\s*$:)
{
- $line = "$function_db->{\"$function RET\"} CCTKBindings_Dummy$function($function_db->{\"$function CARGS\"})\n";
+ $ret = $function_db->{"$function RET"};
+
+ $line = "$ret CCTKBindings_Dummy$function($function_db->{\"$function CARGS\"});\n";
+ push(@data, $line);
+ $line = "$ret CCTKBindings_Dummy$function($function_db->{\"$function CARGS\"})\n";
push(@data, $line);
$line = "{\n";
push(@data, $line);
- $line = " CCTK_Warn(0,__LINE__,__FILE__,\"Bindings\",\n";
+
+ # Make sure we use all arguments to avoid warnings
+ $line = " CCTK_INT cctk_dummy_int;\n";
+ push(@data, $line);
+ $line = " CCTK_REAL cctk_dummy_real;\n";
+ push(@data, $line);
+ $line = " void *cctk_dummy_pointer;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_int=0;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_int+=0;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_real=0;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_real+=0;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_pointer=NULL;\n";
+ push(@data, $line);
+ $line = " cctk_dummy_pointer=(CCTK_REAL *)cctk_dummy_pointer;\n";
+ push(@data, $line);
+ foreach $arg (split(",",$function_db->{"$function CARGS"}))
+ {
+ $arg =~ m:(.*\s+\**)([^\s*\*]+)\s*:;
+ $type=$1;
+ $name=$2;
+ if ($type =~ /[^\*]*\*\s*/ && $type !~ "const")
+ {
+ $line = " cctk_dummy_pointer=(void *)$name;\n";
+ push(@data, $line);
+ }
+ elsif ($type =~ /int/i)
+ {
+ $line = " cctk_dummy_int=$name;\n";
+ push(@data, $line);
+ }
+ elsif ($type =~ /real/i)
+ {
+ $line = " cctk_dummy_real=$name;\n";
+ push(@data, $line);
+ }
+ }
+ $line = " CCTK_Warn(1,__LINE__,__FILE__,\"Bindings\",\n";
push(@data, $line);
$line = " \"CCTKBindings_Dummy$function: Calling thorn function $function which has not been overloaded\");\n";
push(@data, $line);
+ if ($ret =~ m:INT:i)
+ {
+ $line = "return -1;";
+ push(@data, $line);
+ }
+ elsif ($ret =~ m:REAL:i)
+ {
+ $line = "return 0;";
+ push(@data, $line);
+ }
$line = "}\n\n";
push(@data, $line);
}
@@ -378,12 +835,12 @@ sub DummyThornFunctions
sub RegisterThornFunctions
{
my($thorn,$function_db,$rhinterface_db) = @_;
- my($dataout,$line,@data);
+ my($dataout,$line,@data,$function);
# Header Data
$line = "/*\@\@\n";
push(@data, $line);
- $line = " \@header RegisterThornFunctions.h\n";
+ $line = " \@header $thorn"."_Register.h\n";
push(@data, $line);
$line = " \@desc\n";
push(@data, $line);
@@ -400,27 +857,46 @@ sub RegisterThornFunctions
{
if ($function !~ m:^\s*$:)
{
- $line = "$function_db->{\"$function RET\"} $rhinterface_db->{\"\U$thorn PROVIDES FUNCTION\E $function WITH\"}($function_db->{\"$function CARGS\"});\n";
- push(@data, $line);
+ $provided_with = $rhinterface_db->{"\U$thorn PROVIDES FUNCTION\E $function WITH"};
+ $ret = $function_db->{"$function RET"};
+ $args = $function_db->{"$function CARGS"};
+
+ $line = "$ret $provided_with($args);\n";
+ push(@data, $line);
+ $line = "int CCTKBindings_Overload$function($ret (* $function)($args));\n";
+ push(@data, $line);
}
}
- $line = "int ".$thorn."_RegisterAliases(void);\n";
+ $line = "\n";
push(@data, $line);
- $line = "int ".$thorn."_RegisterAliases(void)\n";
+ $line = "int CCTKBindings_".$thorn."Aliases(void);\n";
+ push(@data, $line);
+ $line = "\n";
+ push(@data, $line);
+ $line = "int CCTKBindings_".$thorn."Aliases(void)\n";
push(@data, $line);
$line = "{\n";
push(@data, $line);
+ $line = " int retval=0; /* returns minus number of failed overloads */\n";
+ push(@data, $line);
+ $line = " int ierr=0;\n\n";
+ push(@data, $line);
+ $line = " retval = ierr; /* use ierr to prevent warnings */\n\n";
+ push(@data, $line);
+
foreach $function (split(" ",$rhinterface_db->{"\U$thorn PROVIDES FUNCTION\E"}))
{
if ($function !~ m:^\s*$:)
{
- $line = "CCTKBindings_Overload$function($rhinterface_db->{\"\U$thorn PROVIDES FUNCTION\E $function WITH\"});\n";
+ $line = " ierr = CCTKBindings_Overload$function($rhinterface_db->{\"\U$thorn PROVIDES FUNCTION\E $function WITH\"});\n";
+ push(@data, $line);
+ $line = " retval = (ierr == 0) ? retval-- : retval;\n";
push(@data, $line);
}
}
- $line = "return 0;\n";
+ $line = " return retval;\n";
push(@data, $line);
$line = "}\n";
push(@data, $line);
@@ -453,7 +929,7 @@ sub RegisterThornFunctions
sub FortranThornFunctions
{
my($function_db) = @_;
- my($dataout,$line,@data);
+ my($dataout,$line,@data,$function);
# Header Data
$line = "/*\@\@\n";
@@ -468,42 +944,53 @@ sub FortranThornFunctions
push(@data, $line);
$line = " \@\@*/\n\n";
push(@data, $line);
+ $line = "\#include <stdlib.h>\n\n";
+ push(@data, $line);
$line = "\#include \"cctk_Flesh.h\"\n";
push(@data, $line);
$line = "\#include \"cctk_WarnLevel.h\"\n\n";
push(@data, $line);
- $line = "\#include \"cctk_FunctionAliases.h\"\n\n";
- push(@data, $line);
$line = "\#include \"cctk_FortranString.h\"\n\n";
push(@data, $line);
+ # Do aliased function prototypes
foreach $function (split(" ",$function_db->{"FUNCTIONS"}))
{
if ($function !~ m:^\s*$:)
{
- $line = "$function_db->{\"$function RET\"} CCTK_FCALL CCTK_FNAME($function)\n";
- push(@data, $line);
- $line = "($function_db->{\"$function WARGS\"}";
- push(@data, $line);
+ $line = "extern $function_db->{\"$function RET\"} (*$function)($function_db->{\"$function CARGS\"});\n";
+ push(@data, $line);
+ }
+ }
+ $line = "\n\n";
+ push(@data, $line);
+
+ foreach $function (split(" ",$function_db->{"FUNCTIONS"}))
+ {
+ if ($function !~ m:^\s*$:)
+ {
+ $line = "$function_db->{\"$function RET\"} CCTK_FCALL CCTK_FNAME($function)\n";
+ $line .= "($function_db->{\"$function WARGS\"}";
if ($function_db->{"$function STRINGS"} == 1)
{
- $line = ", ONE_FORTSTRING_ARG";
- push(@data, $line);
+ $line .= ", ONE_FORTSTRING_ARG";
}
elsif ($function_db->{"$function STRINGS"} == 2)
{
- $line = ", TWO_FORTSTRINGS_ARGS";
- push(@data, $line);
+ $line .= ", TWO_FORTSTRINGS_ARGS";
}
elsif ($function_db->{"$function STRINGS"} == 3)
{
- $line = ", THREE_FORTSTRINGS_ARGS";
- push(@data, $line);
+ $line .= ", THREE_FORTSTRINGS_ARGS";
}
- $line = ")\n";
- push(@data, $line);
+ $line .= ")";
+
+ # prototype
+ push(@data, "$line;\n");
+ # call
+ push(@data, "$line\n");
$line = "{\n";
push(@data, $line);
@@ -611,21 +1098,36 @@ sub FortranThornFunctions
sub FunctionDatabase
{
my($rhinterface_db) = @_;
+ my($thorn,$inret,$inargs,$message,$function);
+
+ $function_db->{"FUNCTIONS"}= " ";
+ $function_db->{"PROVIDED FUNCTIONS"}= " ";
- foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
+ # Add used functions to database
+ foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
{
-# print "$thorn\n";
- foreach $function (split(" ",($rhinterface_db->{"\U$thorn FUNCTIONS\E"})))
+ foreach $function (split(" ",($rhinterface_db->{"\U$thorn USES FUNCTION\E"})))
{
-# print " Dealing with $function\n";
- if ($function_db->{"FUNCTIONS"} =~ /$function/ && $function !~ /^\s*$/)
+ $inargs = $rhinterface_db->{"\U$thorn FUNCTION\E $function ARGS"};
+ $inret = $rhinterface_db->{"\U$thorn FUNCTION\E $function RET"};
+
+ ($nstrings,$types,$c,$fortran,$wrappercall,$wrapperargs,$cargs) = &ParseArguments($inret,$inargs);
+
+ if ($function_db->{"FUNCTIONS"} =~ / $function / && $function !~ /^\s*$/)
{
-# print " Found $function in database\n";
+ if ($types ne $function_db->{"$function TYPES"})
+ {
+ $message = "Argument types for aliased $function do not match";
+ &CST_error(0,$message,__LINE__,__FILE__);
+ }
+ if ($inret ne $function_db->{"$function RET"})
+ {
+ $message = "Return types for aliased $function do not match";
+ &CST_error(0,$message,__LINE__,__FILE__);
+ }
}
else
{
- $inargs = $rhinterface_db->{"\U$thorn FUNCTION\E $function ARGS"};
- $inret = $rhinterface_db->{"\U$thorn FUNCTION\E $function RET"};
if ($inret =~ m:^\s*void\s*$:)
{
$function_db->{"$function CARGS"} = "SUB";
@@ -635,22 +1137,39 @@ sub FunctionDatabase
$function_db->{"$function CARGS"} = "FUNC";
}
- ($nstrings,$fortran,$wrappercall,$wrapperargs,$cargs) = &ParseArguments($inret,$inargs);
+ if ($c)
+ {
+ if ($fortran)
+ {
+ $function_db->{"$function LANG"} = "FC";
+ }
+ else
+ {
+ $function_db->{"$function LANG"} = "C";
+ $message = "Fortran wrapper not created for alias $function";
+ &CST_error(1,$message,__LINE__,__FILE__);
+ }
+ }
+ else
+ {
+ $function_db->{"$function LANG"} = "";
+ $message = "Can't create alias for $function";
+ &CST_error(0,$message,__LINE__,__FILE__);
+ }
- if ($fortran)
+ if ($rhinterface_db->{"\U$thorn FUNCTION\E $function RET"} eq "void")
{
- $function_db->{"$function LANG"} = "FC";
+ $function_db->{"$function TYPE"} = "SUB";
}
else
{
- $message = "Fortran wrapper not created for alias $function";
- &CST_error(1,$message,__LINE__,__FILE__);
- $function_db->{"$function LANG"} = "C";
+ $function_db->{"$function TYPE"} = "FUNC";
}
$function_db->{"FUNCTIONS"} .= "$function ";
$function_db->{"$function STRINGS"} = $nstrings;
$function_db->{"$function CARGS"} = $cargs;
+ $function_db->{"$function TYPES"} = $types;
$function_db->{"$function WARGS"} = $wrapperargs;
$function_db->{"$function WCALL"} = $wrappercall;
$function_db->{"$function RET"} = $rhinterface_db->{"\U$thorn FUNCTION\E $function RET"};
@@ -658,6 +1177,43 @@ sub FunctionDatabase
}
}
+ # Check consistency of providing functions
+ foreach $thorn (split(" ",$rhinterface_db->{"THORNS"}))
+ {
+ foreach $function (split(" ",($rhinterface_db->{"\U$thorn PROVIDES FUNCTION\E"})))
+ {
+ $inargs = $rhinterface_db->{"\U$thorn FUNCTION\E $function ARGS"};
+ $inret = $rhinterface_db->{"\U$thorn FUNCTION\E $function RET"};
+
+ ($nstrings,$types,$c,$fortran,$wrappercall,$wrapperargs,$cargs) = &ParseArguments($inret,$inargs);
+
+ if ($function_db->{"FUNCTIONS"} =~ / $function / && $function !~ /^\s*$/)
+ {
+ if ($types ne $function_db->{"$function TYPES"})
+ {
+ $message = "Argument types for aliased $function do not match";
+ &CST_error(0,$message,__LINE__,__FILE__);
+ }
+ if ($inret ne $function_db->{"$function RET"})
+ {
+ $message = "Return types for aliased $function do not match";
+ &CST_error(0,$message,__LINE__,__FILE__);
+ }
+ }
+ $function_db->{"PROVIDED FUNCTIONS"} .= "$function ";
+ }
+ }
+
+ # Check to see if any functions are potentially used and not provided
+ foreach $function (split(" ",($function_db->{"FUNCTIONS"})))
+ {
+ if ($function_db->{"PROVIDED FUNCTIONS"} !~ / $function /)
+ {
+ $message = "Aliased function $function is not provided by any thorn";
+ &CST_error(1,$message,__LINE__,__FILE__);
+ }
+ }
+
return $function_db;
}
@@ -681,50 +1237,76 @@ sub ParseArguments
my($ret,$args) = @_;
my($number_args);
- print "\n\nInput args is $args\n\n";
+# print "\nParsing Arguments\n";
+# print "=================\n";
+# print "All args: $args\n";
- $fwrapperargs = "";
+ $fwrapperargs = "";
$fwrappercallargs = "";
- $ccallargs = "";
-
+ $ccallargs = "";
+ $types = "";
$number_args = split(",",$args);
+
+ # Need to count strings for fortran wrappers
$number_strings = 0;
+
+ # Will be set to zero if can't generate a fortran wrapper
$fortran = 1;
+ # Will be set to zero if can't add the aliased C function
+ $c = 1;
foreach $arg (split(",",$args))
{
- print "arg is $arg\n";
+
+# print " Arg is $arg\n";
+
# last part is the argument name
$arg =~ m:(.*)\s+([^\s]+)\s*:;
$name = $2;
$type = $1;
-
+ $name =~ s:^\s*::;
+ $name =~ s:\s*$::;
+ $type =~ s:^\s*::;
+ $type =~ s:\s*$::;
+
+ $types = "$types $type";
+
+# print " Name is $name\n";
+# print " Type is $type\n";
+
# treat string differently
- if ($type =~ m/char/)
+ if ($type =~ m/CCTK_STRING/)
{
$number_strings++;
$ccallargs .= "$type $name, ";
}
- else
+ elsif ($type =~ m/CCTK_INT/ || $type =~ m/CCTK_REAL/)
{
if ($number_strings)
{
$fortran = 0;
}
# look for an array
- if ($type =~ m/(.*)(:ARRAY|:\*)\s*/ && $type !~ /const char/i)
- {
- $ccallargs .= "$1 *$name, ";
- $fwrapperargs .= "$1 *$name, ";
- $fwrappercallargs .= "$name, ";
- }
+ if ($type =~ m/^\s*(CCTK_INT??|CCTK_REAL??):ARRAY\s*$/)
+ {
+ $ccallargs .= "$1 *$name, ";
+ $fwrapperargs .= "$1 *$name, ";
+ $fwrappercallargs .= "$name, ";
+ }
else
- {
- $ccallargs .= "$type $name, ";
- $fwrapperargs .= "$type *$name, ";
- $fwrappercallargs .= "*$name, ";
- }
+ {
+ $ccallargs .= "$type $name, ";
+ $fwrapperargs .= "$type *$name, ";
+ $fwrappercallargs .= "*$name, ";
+ }
+ }
+ else
+ {
+ $fortran = 0;
+ $c = 0;
+ $message = "Error parsing aliased function argument $arg";
+ &CST_error(1,$message,__LINE__,__FILE__);
}
}
@@ -739,7 +1321,7 @@ sub ParseArguments
$fortran = 0;
}
- return ($number_strings,$fortran,$fwrappercallargs,$fwrapperargs,$ccallargs);
+ return ($number_strings,$types,$c,$fortran,$fwrappercallargs,$fwrapperargs,$ccallargs);
}
1;
diff --git a/lib/sbin/interface_parser.pl b/lib/sbin/interface_parser.pl
index fcb72696..cc83eeb5 100644
--- a/lib/sbin/interface_parser.pl
+++ b/lib/sbin/interface_parser.pl
@@ -605,7 +605,7 @@ sub parse_interface_ccl
$interface_db{"\U$thorn PRIVATE GROUPS\E"} = "";
$interface_db{"\U$thorn USES HEADER\E"} = "";
$interface_db{"\U$thorn FUNCTIONS\E"} = "";
- $interface_db{"\U$thorn PROVIDES FUNCTION\E"} = "";
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E"} = "";
$interface_db{"\U$thorn USES FUNCTION\E"} = "";
$interface_db{"\U$thorn ARRANGEMENT\E"} = "$arrangement";
@@ -645,6 +645,68 @@ sub parse_interface_ccl
{
$block = "\U$1\E";
}
+ elsif ($line =~ m/^\s*PROVIDES\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*WITH\s*(.+)\s*$/i)
+ {
+ $funcname = $1;
+ $provided_by = $2;
+
+ if($provided_by =~ m/(.*)\s*LANGUAGE\s*(.+)/i)
+ {
+ $provided_by = $1;
+ $provided_by_language = $2;
+ }
+ else
+ {
+ $provided_by_language = "Fortran";
+ }
+
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E"} .= "$funcname ";
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname WITH"} .= "$provided_by ";
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname LANG"} .= "$provided_by_language ";
+
+ }
+ elsif ($line =~ m/^\s*USES\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*$/i)
+ {
+ $funcname = $1;
+ $interface_db{"\U$thorn USES FUNCTION\E"} .= "$funcname ";
+ }
+ elsif ($line =~ m/^\s*([a-zA-Z_0-9]+)\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*(.*)\s*$/i)
+ {
+ $rettype = $1;
+ $funcname = $2;
+ $rest = $3;
+ if($rest =~ m/(.*)\s*PROVIDED-BY\s*(.+)/i)
+ {
+ $funcargs = $1;
+ $provided_by = $2;
+
+ if($provided_by =~ m/(.*)\s*LANGUAGE\s*(.+)/i)
+ {
+ $provided_by = $1;
+ $provided_by_language = $2;
+ }
+ else
+ {
+ $provided_by_language = "Fortran";
+ }
+ }
+ else
+ {
+ $funcargs = $rest;
+ $provided_by = "";
+ }
+
+ $interface_db{"\U$thorn FUNCTIONS\E"} .= "$funcname ";
+ $interface_db{"\U$thorn FUNCTION\E $funcname ARGS"} .= "$funcargs";
+ $interface_db{"\U$thorn FUNCTION\E $funcname RET"} .= "$rettype";
+
+ if($provided_by ne "")
+ {
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E"} .= "$funcname";
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname WITH"} .= "$provided_by";
+ $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname LANG"} .= "$provided_by_language";
+ }
+ }
elsif ($line =~ m/^\s*(CCTK_)?(INT|INT2|INT4|INT8|REAL|REAL4|REAL8|REAL16|CHAR|COMPLEX)\s*([a-zA-Z]+[a-zA-Z_0-9]*)\s*(.*)\s*$/i)
{
$current_group = "$3";
@@ -849,68 +911,6 @@ sub parse_interface_ccl
# print "Adding $header to $4\n";
$interface_db{"\U$thorn ADD HEADER $header TO\E"} = $4;
}
- elsif ($line =~ m/^\s*PROVIDE\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*WITH\s*(.+)\s*$/i)
- {
- $funcname = $1;
- $provided_by = $2;
-
- if($provided_by =~ m/(.*)\s*LANGUAGE\s*(.+)/i)
- {
- $provided_by = $1;
- $provided_by_language = $2;
- }
- else
- {
- $provided_by_language = "Fortran";
- }
-
- $interface_db{"\U$thorn PROVIDES FUNCTION\E"} .= "$funcname";
- $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname WITH"} .= "$provided_by";
- $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname LANG"} .= "$provided_by_language";
-
- }
- elsif ($line =~ m/^\s*USES\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*$/i)
- {
- $funcname = $1;
- $interface_db{"\U$thorn USES FUNCTION\E"} .= "$funcname";
- }
- elsif ($line =~ m/^\s*([a-zA-Z_0-9]+)\s*FUNCTION\s*([a-zA-Z_0-9]+)\s*(.*)\s*$/i)
- {
- $rettype = $1;
- $funcname = $2;
- $rest = $3;
- if($rest =~ m/(.*)\s*PROVIDED-BY\s*(.+)/i)
- {
- $funcargs = $1;
- $provided_by = $2;
-
- if($provided_by =~ m/(.*)\s*LANGUAGE\s*(.+)/i)
- {
- $provided_by = $1;
- $provided_by_language = $2;
- }
- else
- {
- $provided_by_language = "Fortran";
- }
- }
- else
- {
- $funcargs = $rest;
- $provided_by = "";
- }
-
- $interface_db{"\U$thorn FUNCTIONS\E"} .= "$funcname";
- $interface_db{"\U$thorn FUNCTION\E $funcname ARGS"} .= "$funcargs";
- $interface_db{"\U$thorn FUNCTION\E $funcname RET"} .= "$rettype";
-
- if($provided_by ne "")
- {
- $interface_db{"\U$thorn PROVIDES FUNCTION\E"} .= "$funcname";
- $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname WITH"} .= "$provided_by";
- $interface_db{"\U$thorn PROVIDES FUNCTION\E $funcname LANG"} .= "$provided_by_language";
- }
- }
else
{
if($line =~ m:\{:)
diff --git a/src/include/cctk.h b/src/include/cctk.h
index abda254f..9d119ee2 100644
--- a/src/include/cctk.h
+++ b/src/include/cctk.h
@@ -86,6 +86,7 @@
#include "cctk_Complex.h"
#include "cctk_File.h"
#include "cctk_Flesh.h"
+#include "cctk_FunctionAliases.h"
#include "cctk_GHExtensions.h"
#include "cctk_Groups.h"
#include "cctk_GroupsOnGH.h"
diff --git a/src/main/InitialiseCactus.c b/src/main/InitialiseCactus.c
index eff9d19a..efad6a52 100644
--- a/src/main/InitialiseCactus.c
+++ b/src/main/InitialiseCactus.c
@@ -117,6 +117,8 @@ int CCTKi_InitialiseCactus(int *argc, char ***argv, tFleshConfig *ConfigData)
CCTKi_BindingsVariablesInitialise();
+ CCTKBindings_RegisterThornFunctions();
+
CCTKi_InitialiseScheduler(ConfigData);
CCTKi_CallStartupFunctions(ConfigData);
diff --git a/src/main/Subsystems.c b/src/main/Subsystems.c
index 691b5620..4400dc01 100644
--- a/src/main/Subsystems.c
+++ b/src/main/Subsystems.c
@@ -60,10 +60,10 @@ int CCTKi_InitialiseSubsystemDefaults(void)
CCTKi_SetupMainFunctions();
CCTKi_SetupCommFunctions();
CCTKi_SetupIOFunctions();
-
+ CCTKBindings_SetupThornFunctions();
CCTKi_BindingsImplementationsInitialise();
CCTKi_BindingsParametersInitialise();
-
+
return 0;
}