#! /usr/bin/perl -s #/*@@ # @file CST # @date Sep 1998 # @author Tom Goodale # @desc # Parses the the configuration files for thorns. # @enddesc # @version $Header $ #@@*/ # Global parameter to track the number of errors from the CST # The file make.thornlist is only created if the number of errors # is zero. $CST_errors = 0; ########################################################################## # Parse the command line $activethorns = shift(@ARGV); if (! $activethorns) { printf "Usage: CST [-top=] [-config_dir=] [-cctk_home=] -bindings_dir= ActiveThornList"; exit; } if(! $top) { $top = `pwd`; } if(! $config_dir) { $config_dir = "$top/config-data"; } # Set up the CCTK home directory if(! $cctk_home) { $cctk_home = $ENV{'CCTK_HOME'} || "$ENV{HOME}/CCTK"; $cctk_home =~ s:/$::g; } if(! $bindings_dir) { $bindings_dir = "$top/bindings"; } ######################################################################## # Require certain packages $sbin_dir = "$cctk_home/lib/sbin"; if (!-e "$sbin_dir/parameter_parser.pl" ) { die "Unable to find CCTK sbin directory - tried $sbin_dir\n"; } require "$sbin_dir/parameter_parser.pl"; require "$sbin_dir/interface_parser.pl"; require "$sbin_dir/schedule_parser.pl"; require "$sbin_dir/create_c_stuff.pl"; require "$sbin_dir/create_fortran_stuff.pl"; require "$sbin_dir/GridFuncStuff.pl"; require "$sbin_dir/output_config.pl"; require "$sbin_dir/Orderer.pl"; require "$sbin_dir/ImpParamConsistency.pl"; ####################################################################### # # Main Program # ###################################################################### # Find out which thorns we have and the location of the ccl files. %thorns = &CreateThornList($cctk_home, $activethorns); # Parse the interface.ccl files %interface_database = &create_interface_database(%thorns); if($debug_interface) { &print_interface_database(%interface_database); } # Parse the parameter.ccl files %parameter_database = &create_parameter_database(%thorns); %parameter_database = &CheckImpParamConsistency(scalar(keys %interface_database), %interface_database, %parameter_database); if($debug_parameters) { &print_parameter_database(%parameter_database); } # Create all the bindings &CreateBindings($bindings_dir, scalar(keys %parameter_database), %parameter_database, %interface_database); # Create header file of active thorns for the code @activethornsheader = &CreateActiveThornsHeader(%thorns); &OutputFile("$bindings_dir/include/", "thornlist.h", @activethornsheader); # Finally (must be last), create the make.thornlist file. @make_thornlist = &CreateMakeThornlist(%thorns); # Stop the make process if there were any errors if ($CST_errors) { if ($CST_errors == 1) { $comment1 = "was 1 error"; $comment2 = "This"; } else { $comment1 = "were $CST_errors errors"; $comment2 = "These"; } print "\n\n------------------------------------------------------\n"; print "There $comment1 during execution of the CST\n"; print "$comment2 must be corrected before compilation can proceed\n"; print "------------------------------------------------------\n\n"; exit(1); } &OutputFile($config_dir, "make.thornlist", @make_thornlist); exit; ############################################################################# # # Subroutines # ############################################################################# #/*@@ # @routine CreateThornList # @date Thu Jan 28 15:18:45 1999 # @author Tom Goodale # @desc # Parses the ActiveThorns file and extracts the thorn names. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateThornList { local($cctk_home, $activethorns) = @_; local(%thornlist); local($thorn, $package, $thorn_name); open(ACTIVE, "<$activethorns") || die "Cannot open ActiveThorns file $activethorns !"; # Put a reference to the main cctk sources in. $thornlist{"Cactus"} = "$cctk_home/src"; # print "cctk_home is $cctk_home\n"; # Loop through the lines of the file. while() { #Ignore comments. s/\#(.*)$//g; s/\n//g; # Different from chop... #Ignore blank lines next if (m:^\s*$:); foreach $thorn (split(' ')) { $thorn =~ m:(.*)[/\\](.*):; $package = $1; $thorn_name = $2; # No longer strip thorn_ off the beginning of a thorn name. # $thorn_name =~ s/thorn_//; if( -r "$cctk_home/packages/$thorn/param.ccl" && -r "$cctk_home/packages/$thorn/interface.ccl" && -r "$cctk_home/packages/$thorn/schedule.ccl") { if( $thornlist{"$thorn_name"} ) { print "Ignoring duplicate thorn $thorn_name\n"; } else { $thornlist{"$thorn_name"} = "$cctk_home/packages/$thorn"; } } else { print "Ignoring $thorn - missing ccl file(s)\n"; next; } } } close ACTIVE; return %thornlist; } #/*@@ # @routine get_public_parameters # @date Thu Jan 28 15:21:52 1999 # @author Tom Goodale # @desc # Gets a list of all public parameters and the throns they are in. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub get_public_parameters { local(%parameter_database) = @_; local(%public_parameters); local($param); foreach $param (split(/ /,$parameter_database{"PUBLIC PARAMETERS"})) { if($param =~ m/(.*)::(.*)/) { $public_parameters{"$2"} = $1; } } return %public_parameters; } #/*@@ # @routine CreateMakeThornlist # @date Thu Jan 28 15:22:31 1999 # @author Tom Goodale # @desc # Creates the lines which should be placed in the make.thornlist file. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateMakeThornlist { local(%thorns) = @_; local($thorn); local($thornlist); $thornlist = "THORNS ="; foreach $thorn (keys %thorns) { # Ignore the main sources - they are dealt with separately next if ($thorn =~ m:Cactus:); $thorns{$thorn} =~ m:(.*)/(.*)/(.*):; # Only place package_name/thorn_name in the file. $thornlist .= " $2/$3"; } return ("$thornlist", ""); } #/*@@ # @routine CreateActiveThornsHeader # @date Wed Feb 17 16:06:20 1999 # @author Gabrielle Allen # @desc # Creates the lines which should be placed in the thornlist.h # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateActiveThornsHeader { local(%thorns) = @_; local($header,$thorn,$nthorns); $nthorns = 0; $header = "\/* List of active thorns in the code. *\/\n\n"; $header .= "static char *thorn_name[] = {\n"; foreach $thorn (keys %thorns) { # Ignore the main sources - they may confuse next if ($thorn =~ m:Cactus:); $thorns{$thorn} =~ m:(.*)/(.*)/(.*):; $nthorns++; # Only place package_name/thorn_name in the file. $header .= "\"$2/$3\",\n"; } $header .= "\"\"};\n\n"; $header .= "static int nthorns = $nthorns;\n\n"; return ("$header", ""); } #/*@@ # @routine CreateBindings # @date Thu Jan 28 15:24:53 1999 # @author Tom Goodale # @desc # All the perl generated stuff is finally placed into the bindings 'thorn'. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateBindings { local($bindings_dir, $n_param_database, @rest) = @_; local(%parameter_database); local(%interface_database); local($start_dir); # Extract the parameter and interface databases from the arguments. %parameter_database = @rest[0..2*$n_param_database-1]; %interface_database = @rest[2*$n_param_database..$#rest]; # Create the bindings directory if it doesn't exist. if(! -d $bindings_dir) { mkdir("$bindings_dir", 0755) || die "Unable to create $bindings_dir"; } # Remember where we started. $start_dir = `pwd`; # Create the bindings for the subsystems. &CreateParameterBindings($bindings_dir, $n_param_database, @rest); &CreateVariableBindings($bindings_dir, %interface_database); &CreateScheduleBindings($bindings_dir, scalar(keys %thorns), %thorns,%interface_database); # Place an appropriate make.code.defn in the bindings directory. chdir $bindings_dir; open (OUT, ">make.code.defn") || die "Cannot open make.code.defn"; print OUT "SRCS = \n"; print OUT "SUBDIRS = Parameters Variables Schedule\n"; close OUT; # Go back to where we started. chdir $start_dir; } #/*@@ # @routine CreateParameterBindings # @date Thu Jan 28 15:27:16 1999 # @author Tom Goodale # @desc # Create the bindings used for the parameters. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateParameterBindings { local($bindings_dir, $n_param_database, @rest) = @_; local(%parameter_database); local(%interface_database); local($start_dir); local($line); local(%these_parameters); local($implementation, $thorn); local($files); local(%routines); local($structure, %structures); local(%header_files); %parameter_database = @rest[0..(2*$n_param_database)-1]; %interface_database = @rest[2*$n_param_database..$#rest]; if(! -d $bindings_dir) { mkdir("$bindings_dir", 0755) || die "Unable to create $bindings_dir"; } $start_dir = `pwd`; chdir $bindings_dir; if(! -d "Parameters") { mkdir("Parameters", 0755) || die "Unable to create Parameters directory"; } if(! -d "include") { mkdir("include", 0755) || die "Unable to create include directory"; } chdir "Parameters"; # Generate all public parameters %these_parameters = &get_public_parameters(%parameter_database); @data = &CreateParameterBindingFile("CCTK_BindingsParametersPublic", "PUBLIC_PARAMETER_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); open (OUT, ">Public.c") || die "Cannot open Public.c"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $files = "Public.c"; $structures{"PUBLIC_PARAMETER_STRUCT"} = "cctk_params_public"; # Generate the public data header file chdir ".."; chdir "include"; @data = &CreateCStructureParameterHeader("CCTK_BindingsParametersPublic", "PUBLIC_PARAMETER_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); open (OUT, ">ParameterCPublic.h") || die "Cannot open ParameterCPublic.h"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $header_files{"PUBLIC"} = "ParameterCPublic.h"; chdir ".."; chdir "Parameters"; # Generate all protected parameters foreach $implementation (split(" ",$interface_database{"IMPLEMENTATIONS"})) { $interface_database{"IMPLEMENTATION \U$implementation\E THORNS"} =~ m:([^ ]+):; $thorn = $1; %these_parameters = &GetThornParameterList($thorn, "PROTECTED", %parameter_database); if((keys %these_parameters > 0)) { @data = &CreateParameterBindingFile("CCTK_BindingsParameters$implementation"."_protected", "PROTECTED_\U$implementation\E_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); open (OUT, ">\U$implementation\E". "_protected.c") || die "Cannot open \U$implementation\E"."_protected.c"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $files .= " \U$implementation\E". "_protected.c"; $routines{"CCTK_BindingsParameters$implementation"."_protected"} = "$implementation"; $structures{"PROTECTED_\U$implementation\E_STRUCT"} = "$implementation"."prot"; # Generate the data header file chdir ".."; chdir "include"; @data = &CreateCStructureParameterHeader("CCTK_BindingsParameters$implementation"."_protected", "PROTECTED_\U$implementation\E_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); open (OUT, ">ParameterCProtected\U$implementation\E".".h") || die "Cannot open ParameterCProtected\U$implementation\E".".h"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $header_files{"\U$implementation\E PROTECTED"} = "ParameterCProtected\U$implementation\E".".h"; chdir ".."; chdir "Parameters"; } } # Generate all private parameters foreach $thorn (split(" ",$interface_database{"THORNS"})) { %these_parameters = &GetThornParameterList($thorn, "PRIVATE", %parameter_database); if((keys %these_parameters > 0)) { @data = &CreateParameterBindingFile("CCTK_BindingsParameters$thorn"."_private", "PRIVATE_\U$thorn\E_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); open (OUT, ">\U$thorn\E"."_private.c") || die "Cannot open \U$thorn\E"."_private.c"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $files .= " \U$thorn\E". "_private.c"; $routines{"CCTK_BindingsParameters$thorn"."_private"} = "$thorn"; # Generate the data header file chdir ".."; chdir "include"; @data = &CreateCStructureParameterHeader("CCTK_BindingsParameters$thorn"."_private", "PRIVATE_\U$thorn\E_STRUCT", scalar(keys %these_parameters), %these_parameters, %parameter_database); $structures{"PRIVATE_\U$thorn\E_STRUCT"} = "$thorn"."priv"; open (OUT, ">ParameterCPrivate\U$thorn\E".".h") || die "Cannot open ParameterCPrivate\U$thorn\E".".h"; foreach $line (@data) { print OUT "$line\n"; } close OUT; $header_files{"\U$thorn\E PRIVATE"} = "ParameterCPrivate\U$thorn\E".".h"; chdir ".."; chdir "Parameters"; } } open (OUT, ">Bindings.c") || die "Cannot open Bindings.c"; print OUT < #include "config.h" #include "Misc.h" EOT foreach $routine ((keys %routines), "CCTK_BindingsParametersPublic") { print OUT "int $routine"."Initialise(void);\n"; print OUT "int $routine"."Set(const char *param, const char *value);\n"; print OUT "int $routine"."Get(const char *param, void **data);\n"; print OUT "int $routine"."Help(const char *param, const char *format, FILE *file);\n"; } print OUT <make.code.defn") || die "Cannot open make.code.defn"; print OUT "SRCS = Bindings.c $files\n"; close OUT; # Create the appropriate thorn parameter headers chdir ".."; chdir "include"; foreach $thorn (split(" ",$interface_database{"THORNS"})) { @data = &CreateFortranThornParameterBindings($thorn, $n_param_database, @rest); open(OUT, ">\U$thorn\E"."_FParameters.h") || die "Cannot open \U$thorn\E"."_FParameters.h"; foreach $line (@data) { print OUT "$line\n"; } close OUT; open(OUT, ">\U$thorn\E"."_CParameters.h") || die "Cannot open \U$thorn\E"."_CParameters.h"; $implementation = $interface_database{"\U$thorn\E IMPLEMENTS"}; print OUT < CParameterStructNames.h") || die "Cannot create CParameterStructNames.h by running c_file_procesor.pl"; foreach $structure (keys %structures) { print OUT "#define $structure FORTRAN_COMMON_NAME($structures{$structure})\n"; } print OUT "\n"; close OUT; open(OUT, ">CParameters.h") || die "Cannot open CParameters.h"; print OUT "#include \"CParameterStructNames.h\"\n\n"; foreach $thorn (split(" ",$interface_database{"THORNS"})) { print OUT "#ifdef THORN_IS_$thorn\n"; print OUT "#include \"\U$thorn\E"."_CParameters.h\"\n"; print OUT "#endif\n\n"; } close OUT; open(OUT, ">FParameters.h") || die "Cannot open FParameters.h"; foreach $thorn (split(" ",$interface_database{"THORNS"})) { print OUT "#ifdef THORN_IS_$thorn\n"; print OUT "#include \"\U$thorn\E"."_FParameters.h\"\n"; print OUT "#endif\n\n"; } close OUT; open(OUT, ">declare_parameters.h") || die "Cannot open declare_parameters.h"; print OUT "#ifdef CCODE\n"; print OUT "#include \"CParameters.h\"\n"; print OUT "#endif\n\n"; print OUT "#ifdef FCODE\n"; print OUT "#include \"FParameters.h\"\n"; print OUT "#endif\n\n"; close OUT; chdir $start_dir; } #/*@@ # @routine CreateScheduleBindings # @date Thu Jan 28 15:27:16 1999 # @author Tom Goodale # @desc # Create the bindings used for the scheduler. # @enddesc # @calls # @calledby # @history # # @endhistory # #@@*/ sub CreateScheduleBindings { local($bindings_dir,$n_thorns,@rest) = @_; local(%thorns); local(%interface_database); local($wrapper, $rfr, $startup, %schedule_data); %thorns = @rest[0..2*$n_thorns-1]; %interface_database = @rest[2*$n_thorns..$#rest]; if(! -d $bindings_dir) { mkdir("$bindings_dir", 0755) || die "Unable to create $bindings_dir"; } $start_dir = `pwd`; chdir $bindings_dir; if(! -d "Schedule") { mkdir("Schedule", 0755) || die "Unable to create Schedule directory"; } chdir "Schedule"; # Parse the schedule.ccl files ($wrapper,$rfr,$startup, %schedule_data) = &create_schedule_code($bindings_dir,$n_thorns,%thorns,%interface_database); @rfr_files = split(" ",$rfr); # Write the contents of BindingsScheduleRegisterRFR.c &create_RegisterRFR($bindings_dir,scalar(@rfr_files), @rfr_files, %schedule_data); # Write the contents of BindingsScheduleRegisterSTARTUP.c &create_RegisterSTARTUP($bindings_dir,split(" ",$startup)); open (OUT, ">Bindings.c") || die "Cannot open Bindings.c"; print OUT <make.code.defn") || die "Cannot open make.code.defn"; $files = ""; foreach $file (split(" ",$rfr),split(" ",$startup),split(" ",$wrapper)) { if($file) { $files = "$files ".$file.".c"; } } print OUT "SRCS = Bindings.c Cactus_RegisterSTARTUP.c Cactus_RegisterRFR.c $files\n"; close OUT; chdir $start_dir; }